aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2024-09-14 20:28:18 -0700
committerPinapelz <yukais@pinapelz.com>2024-09-14 20:28:18 -0700
commitd00b782c7fa6b4b4e68754293a3236e35ed7ff90 (patch)
tree914f331623c73e866291fdbf60eb83dde9a52f36
parent610015a68d7ad9580c7ac9dc427ccace650a9b9e (diff)
implement initial BD websocket receiver
-rw-r--r--.gitignore3
-rw-r--r--.gitmodules3
m---------BDFireToWebsocket0
-rw-r--r--Data/goat.pngbin19708 -> 0 bytes
-rw-r--r--DiscordToXIV.sln (renamed from SamplePlugin.sln)2
-rw-r--r--DiscordToXIV/Configuration.cs (renamed from SamplePlugin/Configuration.cs)2
-rw-r--r--DiscordToXIV/Dalamud.Plugin.Bootstrap.targets (renamed from SamplePlugin/Dalamud.Plugin.Bootstrap.targets)0
-rw-r--r--DiscordToXIV/DiscordToXIV.csproj18
-rw-r--r--DiscordToXIV/DiscordToXIV.json (renamed from SamplePlugin/SamplePlugin.json)4
-rw-r--r--DiscordToXIV/Plugin.cs158
-rw-r--r--DiscordToXIV/Windows/ConfigWindow.cs (renamed from SamplePlugin/Windows/ConfigWindow.cs)25
-rw-r--r--DiscordToXIV/packages.lock.json (renamed from SamplePlugin/packages.lock.json)6
-rw-r--r--README.md78
-rw-r--r--SamplePlugin/Plugin.cs73
-rw-r--r--SamplePlugin/SamplePlugin.csproj19
-rw-r--r--SamplePlugin/Windows/MainWindow.cs58
16 files changed, 195 insertions, 254 deletions
diff --git a/.gitignore b/.gitignore
index 7990fe7..8efa026 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.vs/
obj/
bin/
-*.user \ No newline at end of file
+*.user
+.idea \ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..d3f03cd
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "BDFireToWebsocket"]
+ path = BDFireToWebsocket
+ url = https://github.com/pinapelz/BDFireToWebsocket
diff --git a/BDFireToWebsocket b/BDFireToWebsocket
new file mode 160000
+Subproject 4bef91bec87907601d60f553d24151259d49906
diff --git a/Data/goat.png b/Data/goat.png
deleted file mode 100644
index 4ca06ac..0000000
--- a/Data/goat.png
+++ /dev/null
Binary files differ
diff --git a/SamplePlugin.sln b/DiscordToXIV.sln
index 31c0066..9bcbdd9 100644
--- a/SamplePlugin.sln
+++ b/DiscordToXIV.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29709.97
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamplePlugin", "SamplePlugin\SamplePlugin.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordToXIV", "DiscordToXIV\DiscordToXIV.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/SamplePlugin/Configuration.cs b/DiscordToXIV/Configuration.cs
index 4cdc476..82d14e3 100644
--- a/SamplePlugin/Configuration.cs
+++ b/DiscordToXIV/Configuration.cs
@@ -2,7 +2,7 @@
using Dalamud.Plugin;
using System;
-namespace SamplePlugin;
+namespace DiscordToXIV;
[Serializable]
public class Configuration : IPluginConfiguration
diff --git a/SamplePlugin/Dalamud.Plugin.Bootstrap.targets b/DiscordToXIV/Dalamud.Plugin.Bootstrap.targets
index 11eec9c..11eec9c 100644
--- a/SamplePlugin/Dalamud.Plugin.Bootstrap.targets
+++ b/DiscordToXIV/Dalamud.Plugin.Bootstrap.targets
diff --git a/DiscordToXIV/DiscordToXIV.csproj b/DiscordToXIV/DiscordToXIV.csproj
new file mode 100644
index 0000000..da2914f
--- /dev/null
+++ b/DiscordToXIV/DiscordToXIV.csproj
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="Dalamud.Plugin.Bootstrap.targets"/>
+
+ <PropertyGroup>
+ <Version>0.0.0.1</Version>
+ <Description>A sample plugin.</Description>
+ <PackageProjectUrl>https://github.com/goatcorp/DiscordToXIV</PackageProjectUrl>
+ <PackageLicenseExpression>AGPL-3.0-or-later</PackageLicenseExpression>
+ <IsPackable>false</IsPackable>
+ <RootNamespace>DiscordToXIV</RootNamespace>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Fleck" Version="1.0.13" />
+ </ItemGroup>
+
+</Project>
diff --git a/SamplePlugin/SamplePlugin.json b/DiscordToXIV/DiscordToXIV.json
index c806554..b4469d7 100644
--- a/SamplePlugin/SamplePlugin.json
+++ b/DiscordToXIV/DiscordToXIV.json
@@ -1,6 +1,6 @@
{
- "Author": "your name here",
- "Name": "Sample Plugin",
+ "Author": "pinapelz",
+ "Name": "DiscordToXIV",
"Punchline": "A short one-liner that shows up in /xlplugins.",
"Description": "A description that shows up in /xlplugins. List any major slash-command(s).",
"ApplicableVersion": "any",
diff --git a/DiscordToXIV/Plugin.cs b/DiscordToXIV/Plugin.cs
new file mode 100644
index 0000000..bd8c977
--- /dev/null
+++ b/DiscordToXIV/Plugin.cs
@@ -0,0 +1,158 @@
+using System;
+using Fleck;
+using Dalamud.Game.Command;
+using Dalamud.IoC;
+using Dalamud.Plugin;
+using Dalamud.Plugin.Services;
+using System.Collections.Generic;
+using System.Threading;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Dalamud.Interface.Windowing;
+using DiscordToXIV.Windows;
+
+namespace DiscordToXIV;
+
+
+public class Message
+{
+ [JsonPropertyName("author")]
+ public string Author { get; set; }
+
+ [JsonPropertyName("author_name")]
+ public string AuthorName { get; set; }
+
+ [JsonPropertyName("nickname")]
+ public string Nickname { get; set; }
+
+ [JsonPropertyName("content")]
+ public string Content { get; set; }
+
+ [JsonPropertyName("time")]
+ public string Time { get; set; }
+
+ [JsonPropertyName("channel")]
+ public string Channel { get; set; }
+}
+
+
+
+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 IChatGui ChatGui { get; private set; } = null!;
+ [PluginService] internal static IPluginLog PluginLog { get; private set; } = null!;
+
+ private const string CommandName = "/pdiscordtoxiv";
+ private const int DefaultPort = 8765;
+
+ private WebSocketServer _webSocketServer;
+ private CancellationTokenSource _cancellationTokenSource;
+ private List<IWebSocketConnection> _connectedClients;
+ public Configuration Configuration { get; init; }
+ private ConfigWindow ConfigWindow { get; init; }
+ public readonly WindowSystem WindowSystem = new("SamplePlugin");
+
+ public Plugin()
+ {
+ Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
+ ConfigWindow = new ConfigWindow(this);
+ WindowSystem.AddWindow(ConfigWindow);
+ _cancellationTokenSource = new CancellationTokenSource();
+ _connectedClients = new List<IWebSocketConnection>();
+
+ CommandManager.AddHandler(CommandName, new CommandInfo(OnCommand)
+ {
+ HelpMessage = "Start WebSocket server. Usage: /pdiscordtoxiv [port]"
+ });
+ PluginInterface.UiBuilder.OpenConfigUi += ToggleConfigUI;
+ ChatGui.Print("Plugin starting...");
+ }
+
+ public void Dispose()
+ {
+ StopWebSocketServer();
+ CommandManager.RemoveHandler(CommandName);
+ }
+
+ private void OnCommand(string command, string args)
+ {
+ var port = DefaultPort;
+ if (!string.IsNullOrEmpty(args))
+ {
+ if(args == "stop")
+ {
+ StopWebSocketServer();
+ ChatGui.Print("WebSocket server stop requested");
+ return;
+ }
+ if (!int.TryParse(args, out port) || port <= 0 || port > 65535)
+ {
+ ChatGui.PrintError($"Invalid port number: {args}. Using default port {DefaultPort}.");
+ port = DefaultPort;
+ }
+ }
+
+ StartWebSocketServer(port);
+ ChatGui.Print($"WebSocket server started on port {port}");
+ }
+
+ private void StartWebSocketServer(int port)
+ {
+ StopWebSocketServer();
+
+ _webSocketServer = new WebSocketServer($"ws://0.0.0.0:{port}");
+
+ _webSocketServer.Start(socket =>
+ {
+ socket.OnOpen = () =>
+ {
+ PluginLog.Information("WebSocket connection opened.");
+ _connectedClients.Add(socket);
+ };
+
+ socket.OnClose = () =>
+ {
+ PluginLog.Information("WebSocket connection closed.");
+ _connectedClients.Remove(socket);
+ };
+
+ socket.OnMessage = message =>
+ {
+ try
+ {
+ Message receivedMessage = JsonSerializer.Deserialize<Message>(message);
+ //PluginLog.Information($"Message from {receivedMessage.Nickname}: {receivedMessage.Content}");
+ ChatGui.Print($"[{receivedMessage.AuthorName}] {receivedMessage.Nickname}: {receivedMessage.Content}");
+ }
+ catch (Exception ex)
+ {
+ PluginLog.Error($"Failed to deserialize message: {ex.Message}");
+ }
+ };
+
+ });
+ }
+
+ private void StopWebSocketServer()
+ {
+ if (_webSocketServer != null)
+ {
+ PluginLog.Information("Stopping WebSocket server...");
+
+ foreach (var socket in _connectedClients)
+ {
+ if (socket.IsAvailable)
+ {
+ socket.Close();
+ }
+ }
+
+ _webSocketServer.Dispose();
+ _cancellationTokenSource.Cancel();
+ PluginLog.Information("WebSocket server stopped.");
+ }
+ }
+ public void ToggleConfigUI() => ConfigWindow.Toggle();
+}
diff --git a/SamplePlugin/Windows/ConfigWindow.cs b/DiscordToXIV/Windows/ConfigWindow.cs
index 0a0af98..d386fc3 100644
--- a/SamplePlugin/Windows/ConfigWindow.cs
+++ b/DiscordToXIV/Windows/ConfigWindow.cs
@@ -2,50 +2,29 @@
using System.Numerics;
using Dalamud.Interface.Windowing;
using ImGuiNET;
+
+namespace DiscordToXIV.Windows;
-namespace SamplePlugin.Windows;
public class ConfigWindow : Window, IDisposable
{
private Configuration Configuration;
- // We give this window a constant ID using ###
- // This allows for labels being dynamic, like "{FPS Counter}fps###XYZ counter window",
- // and the window ID will always be "###XYZ counter window" for ImGui
public ConfigWindow(Plugin plugin) : base("A Wonderful Configuration Window###With a constant ID")
{
- Flags = ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollbar |
- ImGuiWindowFlags.NoScrollWithMouse;
-
Size = new Vector2(232, 90);
SizeCondition = ImGuiCond.Always;
-
Configuration = plugin.Configuration;
}
public void Dispose() { }
- public override void PreDraw()
- {
- // Flags must be added or removed before Draw() is being called, or they won't apply
- if (Configuration.IsConfigWindowMovable)
- {
- Flags &= ~ImGuiWindowFlags.NoMove;
- }
- else
- {
- Flags |= ImGuiWindowFlags.NoMove;
- }
- }
-
public override void Draw()
{
- // can't ref a property, so use a local copy
var configValue = Configuration.SomePropertyToBeSavedAndWithADefault;
if (ImGui.Checkbox("Random Config Bool", ref configValue))
{
Configuration.SomePropertyToBeSavedAndWithADefault = configValue;
- // can save immediately on change, if you don't want to provide a "Save and Close" button
Configuration.Save();
}
diff --git a/SamplePlugin/packages.lock.json b/DiscordToXIV/packages.lock.json
index 19fcea9..5c97610 100644
--- a/SamplePlugin/packages.lock.json
+++ b/DiscordToXIV/packages.lock.json
@@ -7,6 +7,12 @@
"requested": "[2.1.13, )",
"resolved": "2.1.13",
"contentHash": "rMN1omGe8536f4xLMvx9NwfvpAc9YFFfeXJ1t4P4PE6Gu8WCIoFliR1sh07hM+bfODmesk/dvMbji7vNI+B/pQ=="
+ },
+ "Fleck": {
+ "type": "Direct",
+ "requested": "[1.0.13, )",
+ "resolved": "1.1.0",
+ "contentHash": "X33W1PqRciRmh8Q23klEv3CiRS681IUJj/Ldlgi96lSfq1Uaux3l1qNewRDboiUxnHfoNtcIhFMIhc9AJ4cw6g=="
}
}
}
diff --git a/README.md b/README.md
index 8419402..c247a23 100644
--- a/README.md
+++ b/README.md
@@ -1,76 +1,2 @@
-> ⚠️ **Don't click Fork!**
->
-> This is a GitHub Template repo. If you want to use this for a plugin, just [use this template][new-repo] to make a new repo!
->
-> ![image](https://github.com/goatcorp/SamplePlugin/assets/16760685/d9732094-e1ed-4769-a70b-58ed2b92580c)
-
-# SamplePlugin
-
-[![Use This Template badge](https://img.shields.io/badge/Use%20This%20Template-0?logo=github&labelColor=grey)][new-repo]
-
-
-Simple example plugin for Dalamud.
-
-This is not designed to be the simplest possible example, but it is also not designed to cover everything you might want to do. For more detailed questions, come ask in [the Discord](https://discord.gg/holdshift).
-
-## Main Points
-
-* Simple functional plugin
- * Slash command
- * Main UI
- * Settings UI
- * Image loading
- * Plugin json
-* Simple, slightly-improved plugin configuration handling
-* Project organization
- * Copies all necessary plugin files to the output directory
- * Does not copy dependencies that are provided by dalamud
- * Output directory can be zipped directly and have exactly what is required
- * Hides data files from visual studio to reduce clutter
- * Also allows having data files in different paths than VS would usually allow if done in the IDE directly
-
-
-The intention is less that any of this is used directly in other projects, and more to show how similar things can be done.
-
-## How To Use
-
-### Getting Started
-
-To begin, [clone this template repository][new-repo] to your own GitHub account. This will automatically bring in everything you need to get a jumpstart on development. You do not need to fork this repository unless you intend to contribute modifications to it.
-
-Be sure to also check out the [Dalamud Developer Docs][dalamud-docs] for helpful information about building your own plugin. The Developer Docs includes helpful information about all sorts of things, including [how to submit][submit] your newly-created plugin to the official repository. Assuming you use this template repository, the provided project build configuration and license are already chosen to make everything a breeze.
-
-[new-repo]: https://github.com/new?template_name=SamplePlugin&template_owner=goatcorp
-[dalamud-docs]: https://dalamud.dev
-[submit]: https://dalamud.dev/plugin-development/plugin-submission
-
-### Prerequisites
-
-SamplePlugin assumes all the following prerequisites are met:
-
-* XIVLauncher, FINAL FANTASY XIV, and Dalamud have all been installed and the game has been run with Dalamud at least once.
-* XIVLauncher is installed to its default directories and configurations.
- * If a custom path is required for Dalamud's dev directory, it must be set with the `DALAMUD_HOME` environment variable.
-* A .NET Core 8 SDK has been installed and configured, or is otherwise available. (In most cases, the IDE will take care of this.)
-
-### Building
-
-1. Open up `SamplePlugin.sln` in your C# editor of choice (likely [Visual Studio 2022](https://visualstudio.microsoft.com) or [JetBrains Rider](https://www.jetbrains.com/rider/)).
-2. Build the solution. By default, this will build a `Debug` build, but you can switch to `Release` in your IDE.
-3. The resulting plugin can be found at `SamplePlugin/bin/x64/Debug/SamplePlugin.dll` (or `Release` if appropriate.)
-
-### Activating in-game
-
-1. Launch the game and use `/xlsettings` in chat or `xlsettings` in the Dalamud Console to open up the Dalamud settings.
- * In here, go to `Experimental`, and add the full path to the `SamplePlugin.dll` to the list of Dev Plugin Locations.
-2. Next, use `/xlplugins` (chat) or `xlplugins` (console) to open up the Plugin Installer.
- * In here, go to `Dev Tools > Installed Dev Plugins`, and the `SamplePlugin` should be visible. Enable it.
-3. You should now be able to use `/pmycommand` (chat) or `pmycommand` (console)!
-
-Note that you only need to add it to the Dev Plugin Locations once (Step 1); it is preserved afterwards. You can disable, enable, or load your plugin on startup through the Plugin Installer.
-
-### Reconfiguring for your own uses
-
-Basically, just replace all references to `SamplePlugin` in all of the files and filenames with your desired name, then start building the plugin of your dreams. You'll figure it out 😁
-
-Dalamud will load the JSON file (by default, `SamplePlugin/SamplePlugin.json`) next to your DLL and use it for metadata, including the description for your plugin in the Plugin Installer. Make sure to update this with information relevant to _your_ plugin!
+# DiscordToXIV
+A Dalamud Plugin that allows you to view Discord messages in chat with the help of BetterDiscord \ No newline at end of file
diff --git a/SamplePlugin/Plugin.cs b/SamplePlugin/Plugin.cs
deleted file mode 100644
index b8e859b..0000000
--- a/SamplePlugin/Plugin.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using Dalamud.Game.Command;
-using Dalamud.IoC;
-using Dalamud.Plugin;
-using System.IO;
-using Dalamud.Interface.Windowing;
-using Dalamud.Plugin.Services;
-using SamplePlugin.Windows;
-
-namespace SamplePlugin;
-
-public sealed class Plugin : IDalamudPlugin
-{
- [PluginService] internal static IDalamudPluginInterface PluginInterface { get; private set; } = null!;
- [PluginService] internal static ITextureProvider TextureProvider { get; private set; } = null!;
- [PluginService] internal static ICommandManager CommandManager { get; private set; } = null!;
-
- private const string CommandName = "/pmycommand";
-
- public Configuration Configuration { get; init; }
-
- public readonly WindowSystem WindowSystem = new("SamplePlugin");
- private ConfigWindow ConfigWindow { get; init; }
- private MainWindow MainWindow { get; init; }
-
- public Plugin()
- {
- Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
-
- // you might normally want to embed resources and load them from the manifest stream
- var goatImagePath = Path.Combine(PluginInterface.AssemblyLocation.Directory?.FullName!, "goat.png");
-
- ConfigWindow = new ConfigWindow(this);
- MainWindow = new MainWindow(this, goatImagePath);
-
- WindowSystem.AddWindow(ConfigWindow);
- WindowSystem.AddWindow(MainWindow);
-
- CommandManager.AddHandler(CommandName, new CommandInfo(OnCommand)
- {
- HelpMessage = "A useful message to display in /xlhelp"
- });
-
- PluginInterface.UiBuilder.Draw += DrawUI;
-
- // This adds a button to the plugin installer entry of this plugin which allows
- // to toggle the display status of the configuration ui
- PluginInterface.UiBuilder.OpenConfigUi += ToggleConfigUI;
-
- // Adds another button that is doing the same but for the main ui of the plugin
- PluginInterface.UiBuilder.OpenMainUi += ToggleMainUI;
- }
-
- public void Dispose()
- {
- WindowSystem.RemoveAllWindows();
-
- ConfigWindow.Dispose();
- MainWindow.Dispose();
-
- CommandManager.RemoveHandler(CommandName);
- }
-
- private void OnCommand(string command, string args)
- {
- // in response to the slash command, just toggle the display status of our main ui
- ToggleMainUI();
- }
-
- private void DrawUI() => WindowSystem.Draw();
-
- public void ToggleConfigUI() => ConfigWindow.Toggle();
- public void ToggleMainUI() => MainWindow.Toggle();
-}
diff --git a/SamplePlugin/SamplePlugin.csproj b/SamplePlugin/SamplePlugin.csproj
deleted file mode 100644
index e952b44..0000000
--- a/SamplePlugin/SamplePlugin.csproj
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project Sdk="Microsoft.NET.Sdk">
- <Import Project="Dalamud.Plugin.Bootstrap.targets"/>
-
- <PropertyGroup>
- <Version>0.0.0.1</Version>
- <Description>A sample plugin.</Description>
- <PackageProjectUrl>https://github.com/goatcorp/SamplePlugin</PackageProjectUrl>
- <PackageLicenseExpression>AGPL-3.0-or-later</PackageLicenseExpression>
- <IsPackable>false</IsPackable>
- </PropertyGroup>
-
- <ItemGroup>
- <Content Include="..\Data\goat.png">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- <Visible>false</Visible>
- </Content>
- </ItemGroup>
-</Project>
diff --git a/SamplePlugin/Windows/MainWindow.cs b/SamplePlugin/Windows/MainWindow.cs
deleted file mode 100644
index 9ac6a4d..0000000
--- a/SamplePlugin/Windows/MainWindow.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System;
-using System.Numerics;
-using Dalamud.Interface.Internal;
-using Dalamud.Interface.Utility;
-using Dalamud.Interface.Windowing;
-using Dalamud.Plugin.Services;
-using ImGuiNET;
-
-namespace SamplePlugin.Windows;
-
-public class MainWindow : Window, IDisposable
-{
- private string GoatImagePath;
- private Plugin Plugin;
-
- // We give this window a hidden ID using ##
- // So that the user will see "My Amazing Window" as window title,
- // but for ImGui the ID is "My Amazing Window##With a hidden ID"
- public MainWindow(Plugin plugin, string goatImagePath)
- : base("My Amazing Window##With a hidden ID", ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse)
- {
- SizeConstraints = new WindowSizeConstraints
- {
- MinimumSize = new Vector2(375, 330),
- MaximumSize = new Vector2(float.MaxValue, float.MaxValue)
- };
-
- GoatImagePath = goatImagePath;
- Plugin = plugin;
- }
-
- public void Dispose() { }
-
- public override void Draw()
- {
- ImGui.Text($"The random config bool is {Plugin.Configuration.SomePropertyToBeSavedAndWithADefault}");
-
- if (ImGui.Button("Show Settings"))
- {
- Plugin.ToggleConfigUI();
- }
-
- ImGui.Spacing();
-
- ImGui.Text("Have a goat:");
- var goatImage = Plugin.TextureProvider.GetFromFile(GoatImagePath).GetWrapOrDefault();
- if (goatImage != null)
- {
- ImGuiHelpers.ScaledIndent(55f);
- ImGui.Image(goatImage.ImGuiHandle, new Vector2(goatImage.Width, goatImage.Height));
- ImGuiHelpers.ScaledIndent(-55f);
- }
- else
- {
- ImGui.Text("Image not found.");
- }
- }
-}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage