Initial commit: HSPosition plugin and plugin-repo for Gitea
Made-with: Cursor
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
||||
# Build
|
||||
bin/
|
||||
obj/
|
||||
*.user
|
||||
*.suo
|
||||
packages/
|
||||
*.dll
|
||||
*.pdb
|
||||
*.zip
|
||||
!plugin-repo/
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
*.csproj.user
|
||||
|
||||
# Keep plugin-repo (manifest)
|
||||
# packages.lock.json
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HSPosition", "HSPosition\HSPosition.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|x64.Build.0 = Debug|x64
|
||||
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|x64.ActiveCfg = Release|x64
|
||||
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B17E85B1-5F60-4440-9F9A-3DDE877E8CDF}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,29 @@
|
||||
using Dalamud.Configuration;
|
||||
using Dalamud.Plugin;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace HSPosition;
|
||||
|
||||
[Serializable]
|
||||
public class Configuration : IPluginConfiguration
|
||||
{
|
||||
public int Version { get; set; } = 1;
|
||||
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>Radius in yalms. Game target ring is ~2–2.5; use MatchGameRingSize in UI to sync.</summary>
|
||||
public float RingRadius { get; set; } = 2.5f;
|
||||
public float RingThickness { get; set; } = 3f;
|
||||
public int RingSegments { get; set; } = 64;
|
||||
|
||||
/// <summary>Degrees added to relative angle before classifying (0–360). Use to align with game if ring color is offset.</summary>
|
||||
public float AngleOffsetDegrees { get; set; } = 0f;
|
||||
/// <summary>If true, flip the angle (use when ring positionals are mirrored).</summary>
|
||||
public bool InvertAngle { get; set; } = false;
|
||||
|
||||
// Colors as RGBA (0-1)
|
||||
public Vector4 ColorFront { get; set; } = new(0.2f, 0.8f, 0.2f, 0.85f); // Green
|
||||
public Vector4 ColorFlank { get; set; } = new(0.9f, 0.7f, 0.1f, 0.85f); // Amber
|
||||
public Vector4 ColorRear { get; set; } = new(0.9f, 0.2f, 0.2f, 0.85f); // Red
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Dalamud.NET.Sdk/14.0.2">
|
||||
<PropertyGroup>
|
||||
<Version>0.0.0.1</Version>
|
||||
<PackageProjectUrl>https://brassnet.ddns.net:33983/Dawnsorrow/HSPosition</PackageProjectUrl>
|
||||
<PackageLicenseExpression>AGPL-3.0-or-later</PackageLicenseExpression>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Name>HSPosition</Name>
|
||||
<Author>HSPosition</Author>
|
||||
<Description>Shows a colored ground ring under your target based on your positional (front, flank, or rear) so you can easily tell if you need to move for abilities.</Description>
|
||||
<Punchline>Ground ring color shows front, flank, or rear for positionals.</Punchline>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="plugin.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<Visible>false</Visible>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,65 @@
|
||||
using Dalamud.Game.Command;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Services;
|
||||
using HSPosition.Windows;
|
||||
|
||||
namespace HSPosition;
|
||||
|
||||
public sealed class Plugin : IDalamudPlugin
|
||||
{
|
||||
[PluginService] internal static IDalamudPluginInterface PluginInterface { get; private set; } = null!;
|
||||
[PluginService] internal static ICommandManager CommandManager { get; private set; } = null!;
|
||||
[PluginService] internal static ITargetManager TargetManager { get; private set; } = null!;
|
||||
[PluginService] internal static IObjectTable ObjectTable { get; private set; } = null!;
|
||||
[PluginService] internal static IGameGui GameGui { get; private set; } = null!;
|
||||
[PluginService] internal static IClientState ClientState { get; private set; } = null!;
|
||||
[PluginService] internal static IPluginLog Log { get; private set; } = null!;
|
||||
|
||||
private const string CommandName = "/hspos";
|
||||
|
||||
public Configuration Configuration { get; }
|
||||
|
||||
private readonly WindowSystem WindowSystem = new("HSPosition");
|
||||
private ConfigWindow ConfigWindow { get; }
|
||||
|
||||
private PositionalOverlay Overlay { get; }
|
||||
|
||||
public Plugin()
|
||||
{
|
||||
Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
|
||||
|
||||
ConfigWindow = new ConfigWindow(this);
|
||||
Overlay = new PositionalOverlay(this);
|
||||
|
||||
WindowSystem.AddWindow(ConfigWindow);
|
||||
|
||||
CommandManager.AddHandler(CommandName, new CommandInfo(OnCommand)
|
||||
{
|
||||
HelpMessage = "Open HSPosition configure (ring color, placement, thickness)"
|
||||
});
|
||||
|
||||
PluginInterface.UiBuilder.Draw += OnDraw;
|
||||
PluginInterface.UiBuilder.OpenConfigUi += () => ConfigWindow.Toggle();
|
||||
|
||||
Log.Information("HSPosition loaded: target ground ring shows front/flank/rear position.");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
PluginInterface.UiBuilder.Draw -= OnDraw;
|
||||
PluginInterface.UiBuilder.OpenConfigUi -= () => { };
|
||||
|
||||
WindowSystem.RemoveAllWindows();
|
||||
CommandManager.RemoveHandler(CommandName);
|
||||
}
|
||||
|
||||
private void OnCommand(string command, string args) => ConfigWindow.Toggle();
|
||||
|
||||
private void OnDraw()
|
||||
{
|
||||
Overlay.Draw();
|
||||
WindowSystem.Draw();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
|
||||
namespace HSPosition;
|
||||
|
||||
/// <summary>
|
||||
/// FFXIV target ring: front = 180° (half circle in front of target), rear = 90° gap at back, flank = sides of back half.
|
||||
/// We use: Front ±90°, Flank 90°–135° and -90° to -135°, Rear 135°–180° and -135° to -180°.
|
||||
/// </summary>
|
||||
public enum Positional
|
||||
{
|
||||
Front,
|
||||
Flank,
|
||||
Rear
|
||||
}
|
||||
|
||||
public class PositionalOverlay
|
||||
{
|
||||
private readonly Plugin plugin;
|
||||
|
||||
public PositionalOverlay(Plugin plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (!plugin.Configuration.Enabled) return;
|
||||
|
||||
var target = Plugin.TargetManager.Target;
|
||||
if (target == null || target.Address == nint.Zero) return;
|
||||
|
||||
var player = Plugin.ObjectTable.LocalPlayer;
|
||||
if (player == null || player.Address == nint.Zero) return;
|
||||
|
||||
var targetPos = target.Position;
|
||||
var targetRot = target.Rotation;
|
||||
var playerPos = player.Position;
|
||||
|
||||
var positional = GetPositional(targetPos, targetRot, playerPos);
|
||||
var color = GetColor(positional);
|
||||
|
||||
DrawGroundRing(targetPos, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the player's positional relative to the target.
|
||||
/// Game: front = 180° half-circle, rear = 90° gap at back, flank = sides (90°–135° from center).
|
||||
/// Target rotation in radians (-π to π). Uses config AngleOffsetDegrees and InvertAngle for alignment.
|
||||
/// </summary>
|
||||
private Positional GetPositional(Vector3 targetPos, float targetRot, Vector3 playerPos)
|
||||
{
|
||||
float dx = playerPos.X - targetPos.X;
|
||||
float dz = playerPos.Z - targetPos.Z;
|
||||
|
||||
if (MathF.Abs(dx) < 1e-5f && MathF.Abs(dz) < 1e-5f)
|
||||
return Positional.Front;
|
||||
|
||||
float angleToPlayer = MathF.Atan2(dx, dz);
|
||||
float relative = angleToPlayer - targetRot;
|
||||
|
||||
if (plugin.Configuration.InvertAngle)
|
||||
relative = -relative;
|
||||
|
||||
relative += plugin.Configuration.AngleOffsetDegrees * (MathF.PI / 180f);
|
||||
|
||||
while (relative > MathF.PI) relative -= 2f * MathF.PI;
|
||||
while (relative < -MathF.PI) relative += 2f * MathF.PI;
|
||||
|
||||
float deg = MathF.Abs(relative * (180f / MathF.PI));
|
||||
|
||||
// Game-style: front = 180° (±90°), flank = sides of back half (90°–135°), rear = back center (135°–180°)
|
||||
if (deg <= 90f) return Positional.Front;
|
||||
if (deg <= 135f) return Positional.Flank;
|
||||
return Positional.Rear;
|
||||
}
|
||||
|
||||
private uint GetColor(Positional p)
|
||||
{
|
||||
var v = p switch
|
||||
{
|
||||
Positional.Front => plugin.Configuration.ColorFront,
|
||||
Positional.Flank => plugin.Configuration.ColorFlank,
|
||||
Positional.Rear => plugin.Configuration.ColorRear,
|
||||
_ => plugin.Configuration.ColorFront
|
||||
};
|
||||
return ImGui.ColorConvertFloat4ToU32(v);
|
||||
}
|
||||
|
||||
private void DrawGroundRing(Vector3 worldCenter, uint color)
|
||||
{
|
||||
var gui = Plugin.GameGui;
|
||||
float r = plugin.Configuration.RingRadius;
|
||||
int segments = Math.Clamp(plugin.Configuration.RingSegments, 8, 128);
|
||||
float thickness = MathF.Max(1f, plugin.Configuration.RingThickness);
|
||||
|
||||
for (int i = 0; i < segments; i++)
|
||||
{
|
||||
float t0 = (float)i / segments * 2f * MathF.PI;
|
||||
float t1 = (float)(i + 1) / segments * 2f * MathF.PI;
|
||||
|
||||
var p0 = worldCenter + new Vector3(r * MathF.Sin(t0), 0, r * MathF.Cos(t0));
|
||||
var p1 = worldCenter + new Vector3(r * MathF.Sin(t1), 0, r * MathF.Cos(t1));
|
||||
|
||||
if (!gui.WorldToScreen(p0, out var s0)) continue;
|
||||
if (!gui.WorldToScreen(p1, out var s1)) continue;
|
||||
|
||||
var drawList = ImGui.GetBackgroundDrawList();
|
||||
drawList.AddLine(s0, s1, color, thickness);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using System.Numerics;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface.Windowing;
|
||||
|
||||
namespace HSPosition.Windows;
|
||||
|
||||
public class ConfigWindow : Window
|
||||
{
|
||||
private readonly Plugin plugin;
|
||||
|
||||
public ConfigWindow(Plugin plugin) : base("HSPosition Configure", ImGuiWindowFlags.AlwaysAutoResize)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
var cfg = plugin.Configuration;
|
||||
|
||||
var enabled = cfg.Enabled;
|
||||
if (ImGui.Checkbox("Enable ground ring", ref enabled))
|
||||
{
|
||||
cfg.Enabled = enabled;
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Text("Ring placement and thickness");
|
||||
ImGui.Spacing();
|
||||
ImGui.TextWrapped("The game's target ring cannot be recolored by plugins. We draw a colored ring on top of it.");
|
||||
if (ImGui.Button("Match game ring size"))
|
||||
{
|
||||
cfg.RingRadius = 2.4f;
|
||||
cfg.RingThickness = 2.5f;
|
||||
cfg.RingSegments = 64;
|
||||
Save();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
|
||||
var ringRadius = cfg.RingRadius;
|
||||
if (ImGui.SliderFloat("Ring radius (yalms)", ref ringRadius, 1f, 8f, "%.1f"))
|
||||
{
|
||||
cfg.RingRadius = ringRadius;
|
||||
Save();
|
||||
}
|
||||
var ringThickness = cfg.RingThickness;
|
||||
if (ImGui.SliderFloat("Ring line thickness", ref ringThickness, 1f, 12f, "%.0f"))
|
||||
{
|
||||
cfg.RingThickness = ringThickness;
|
||||
Save();
|
||||
}
|
||||
var ringSegments = cfg.RingSegments;
|
||||
if (ImGui.SliderInt("Ring segments", ref ringSegments, 16, 128))
|
||||
{
|
||||
cfg.RingSegments = ringSegments;
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Text("Positional angle (if colors feel offset)");
|
||||
ImGui.Spacing();
|
||||
|
||||
var angleOffset = cfg.AngleOffsetDegrees;
|
||||
if (ImGui.SliderFloat("Angle offset (degrees)", ref angleOffset, 0f, 360f, "%.0f"))
|
||||
{
|
||||
cfg.AngleOffsetDegrees = angleOffset;
|
||||
Save();
|
||||
}
|
||||
var invertAngle = cfg.InvertAngle;
|
||||
if (ImGui.Checkbox("Invert angle (mirror front/rear)", ref invertAngle))
|
||||
{
|
||||
cfg.InvertAngle = invertAngle;
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Text("Ring colors (Front / Flank / Rear)");
|
||||
ImGui.Spacing();
|
||||
|
||||
var colorFront = cfg.ColorFront;
|
||||
if (ImGui.ColorEdit4("Front", ref colorFront, ImGuiColorEditFlags.AlphaBar))
|
||||
{
|
||||
cfg.ColorFront = colorFront;
|
||||
Save();
|
||||
}
|
||||
var colorFlank = cfg.ColorFlank;
|
||||
if (ImGui.ColorEdit4("Flank", ref colorFlank, ImGuiColorEditFlags.AlphaBar))
|
||||
{
|
||||
cfg.ColorFlank = colorFlank;
|
||||
Save();
|
||||
}
|
||||
var colorRear = cfg.ColorRear;
|
||||
if (ImGui.ColorEdit4("Rear", ref colorRear, ImGuiColorEditFlags.AlphaBar))
|
||||
{
|
||||
cfg.ColorRear = colorRear;
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.TextWrapped("Our ring is drawn on top of the game's target ring and changes color by your positional (Front / Flank / Rear). Use 'Match game ring size' so they align.");
|
||||
}
|
||||
|
||||
private void Save()
|
||||
{
|
||||
Plugin.PluginInterface.SavePluginConfig(plugin.Configuration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
"net10.0-windows7.0": {
|
||||
"DalamudPackager": {
|
||||
"type": "Direct",
|
||||
"requested": "[14.0.2, )",
|
||||
"resolved": "14.0.2",
|
||||
"contentHash": "dQJeq+8eyHzra4Cg5eZ/3LAeS3/UpvvLriYJGSncMK9LqJ7Q4B6jwcOsxo3PfxVd15xj+IzVFxkPqIBmPQu8/w=="
|
||||
},
|
||||
"DotNet.ReproducibleBuilds": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.2.39, )",
|
||||
"resolved": "1.2.39",
|
||||
"contentHash": "fcFN01tDTIQqDuTwr1jUQK/geofiwjG5DycJQOnC72i1SsLAk1ELe+apBOuZ11UMQG8YKFZG1FgvjZPbqHyatg=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"Name": "HSPosition",
|
||||
"Author": "HSPosition",
|
||||
"Description": "Shows a colored ground ring under your target based on your positional (front, flank, or rear) so you can easily tell if you need to move for abilities.",
|
||||
"Punchline": "Ground ring color shows front, flank, or rear for positionals.",
|
||||
"InternalName": "HSPosition",
|
||||
"AssemblyVersion": "0.0.0.1",
|
||||
"RepoUrl": "https://brassnet.ddns.net:33983/Dawnsorrow/HSPosition",
|
||||
"ApplicableVersion": "any",
|
||||
"DalamudApiLevel": 11,
|
||||
"LoadPriority": 0
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# HSPosition
|
||||
|
||||
A Dalamud plugin for FFXIV that draws a **colored ground ring** under your current target.
|
||||
|
||||
**Publishing to your own repo:** See the `plugin-repo/` folder for a single-repo setup (pluginmaster + README) you can push to Gitea so others can add one URL and get all your plugins. The color reflects your positional:
|
||||
|
||||
- **Green** = Front
|
||||
- **Amber** = Flank
|
||||
- **Red** = Rear
|
||||
|
||||
So you can see at a glance whether you need to move for positional abilities.
|
||||
|
||||
## Build
|
||||
|
||||
- .NET 10 SDK and Dalamud dev install (e.g. XIVLauncher with Dalamud, run game once).
|
||||
- Build: `dotnet build HSPosition.sln -c Debug` (or Release).
|
||||
- Output: `HSPosition/bin/x64/Debug/` (or `Release/`).
|
||||
|
||||
## Install (dev)
|
||||
|
||||
1. **xlsettings** → Experimental → add the full path to `HSPosition.dll` to **Dev Plugin Locations**.
|
||||
2. **xlplugins** → Dev Tools → Installed Dev Plugins → enable **HSPosition**.
|
||||
|
||||
## Usage
|
||||
|
||||
- Target something; a ring appears under it. Color = your current positional (front/flank/rear).
|
||||
- **/hspos** — open configure menu (or use the **Configure** button on the plugin in the installer).
|
||||
- Configure: enable/disable, ring radius, line thickness, segments, angle offset/invert, and colors for front/flank/rear.
|
||||
|
||||
## Positional angles
|
||||
|
||||
- **Front**: ±45° in front of the target.
|
||||
- **Flank**: 45°–135° to the left or right.
|
||||
- **Rear**: 135°–180° behind the target.
|
||||
|
||||
Matches FFXIV’s usual ~90° cones for positionals.
|
||||
@@ -0,0 +1,80 @@
|
||||
# My Dalamud Plugin Repository
|
||||
|
||||
This repo is a **single custom repository** for Dalamud. Users add one URL and see all your plugins in the installer.
|
||||
|
||||
## What users add in Dalamud
|
||||
|
||||
1. Open **xlsettings** (or Dalamud Settings).
|
||||
2. Go to **Experimental** → **Custom Plugin Repositories**.
|
||||
3. Add this URL (use the **raw** URL to `pluginmaster.json` on your Gitea):
|
||||
|
||||
```
|
||||
https://brassnet.ddns.net:33983/Dawnsorrow/DalamudPlugins/raw/main/pluginmaster.json
|
||||
```
|
||||
|
||||
4. Save. In **xlplugins**, your repo will appear and list all plugins in `pluginmaster.json`.
|
||||
|
||||
---
|
||||
|
||||
## Repo layout
|
||||
|
||||
- **pluginmaster.json** – List of all your plugins. This file’s raw URL is the “repo link” users add.
|
||||
- **releases/** – Optional: put `latest.zip` builds here and use raw URLs in pluginmaster (see below).
|
||||
- Or use **Gitea Releases** on this repo for each plugin (recommended).
|
||||
|
||||
---
|
||||
|
||||
## Adding a new plugin to the repo
|
||||
|
||||
1. **Edit `pluginmaster.json`** and add a new object to the array (copy an existing entry and change fields):
|
||||
|
||||
- `Author`, `Name`, `Description`, `Punchline`, `InternalName`
|
||||
- `AssemblyVersion` (e.g. `"0.0.0.1"`)
|
||||
- `RepoUrl` – link to the plugin’s source (can be another Gitea repo or same repo folder)
|
||||
- `ApplicableVersion`: `"any"`
|
||||
- `DalamudApiLevel`: e.g. `14`
|
||||
- `LastUpdate`: Unix timestamp (seconds), e.g. `1730000000`
|
||||
- `DownloadLinkInstall` and `DownloadLinkUpdate`: URL to the plugin’s **zip** (see below)
|
||||
|
||||
2. **Host the plugin zip** in one of these ways:
|
||||
|
||||
**Option A – Releases on this repo (recommended)**
|
||||
- Create a release (e.g. tag `HSPosition-0.0.0.1` or `v0.0.0.1`).
|
||||
- Upload the plugin zip as `latest.zip`.
|
||||
- Use the release download URL in pluginmaster, e.g.
|
||||
`https://brassnet.ddns.net:33983/Dawnsorrow/DalamudPlugins/releases/download/HSPosition-0.0.0.1/latest.zip`
|
||||
|
||||
**Option B – Raw file in repo**
|
||||
- Put `HSPosition-0.0.0.1.zip` in a `releases/` folder and commit.
|
||||
- Use the raw file URL:
|
||||
`https://brassnet.ddns.net:33983/Dawnsorrow/DalamudPlugins/raw/main/releases/HSPosition-0.0.0.1.zip`
|
||||
|
||||
**Option C – Separate repo per plugin**
|
||||
- Build and release each plugin in its own Gitea repo.
|
||||
- In pluginmaster, set `DownloadLinkInstall` / `DownloadLinkUpdate` to that repo’s release zip URL.
|
||||
|
||||
3. This repo is configured for **brassnet.ddns.net:33983** and user **Dawnsorrow**. For new plugins, set download URLs to `https://brassnet.ddns.net:33983/Dawnsorrow/DalamudPlugins/...` (releases or raw).
|
||||
|
||||
---
|
||||
|
||||
## Building and packaging HSPosition (or any plugin)
|
||||
|
||||
1. From the plugin project directory, build in **Release** so the packager produces a zip:
|
||||
```bash
|
||||
dotnet build HSPosition.sln -c Release
|
||||
```
|
||||
2. The zip is at:
|
||||
`HSPosition/bin/x64/Release/HSPosition/latest.zip`
|
||||
3. Upload that zip to a Gitea Release (e.g. create release tag `HSPosition-0.0.0.1`, attach `latest.zip`), or put it in `releases/` and use the raw URL.
|
||||
|
||||
---
|
||||
|
||||
## Updating a plugin
|
||||
|
||||
1. Bump the plugin’s version (e.g. in `.csproj` and `plugin.json`).
|
||||
2. Build in Release and upload the new zip (new release or replace file in `releases/`).
|
||||
3. In `pluginmaster.json` update:
|
||||
- `AssemblyVersion` (and tag/release name if you use it in the URL).
|
||||
- `LastUpdate` (current Unix timestamp: `date +%s`).
|
||||
- `DownloadLinkInstall` and `DownloadLinkUpdate` if the zip URL changed (e.g. new release tag).
|
||||
4. Commit and push. Users will get the update when they check for updates in the plugin installer.
|
||||
@@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"Author": "HSPosition",
|
||||
"Name": "HSPosition",
|
||||
"Punchline": "Ground ring color shows front, flank, or rear for positionals.",
|
||||
"Description": "Shows a colored ground ring under your target based on your positional (front, flank, or rear) so you can easily tell if you need to move for abilities.",
|
||||
"Changelog": "Initial release.",
|
||||
"IsHide": false,
|
||||
"InternalName": "HSPosition",
|
||||
"AssemblyVersion": "0.0.0.1",
|
||||
"TestingAssemblyVersion": null,
|
||||
"IsTestingExclusive": false,
|
||||
"RepoUrl": "https://brassnet.ddns.net:33983/Dawnsorrow/HSPosition",
|
||||
"ApplicableVersion": "any",
|
||||
"DalamudApiLevel": 14,
|
||||
"DownloadCount": 0,
|
||||
"LastUpdate": 1730000000,
|
||||
"DownloadLinkInstall": "https://brassnet.ddns.net:33983/Dawnsorrow/HSPosition/releases/download/HSPosition-0.0.0.1/latest.zip",
|
||||
"DownloadLinkUpdate": "https://brassnet.ddns.net:33983/Dawnsorrow/HSPosition/releases/download/HSPosition-0.0.0.1/latest.zip",
|
||||
"DownloadLinkTesting": null
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user