Texture : register(t0);
3 |
4 | struct Interpolators
5 | {
6 | float4 Position : SV_Position;
7 | float2 TexCoord : TEXCOORD0;
8 | };
9 |
--------------------------------------------------------------------------------
/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [alias]
2 | inject = "run -p grebuloff-injector inject"
3 | launch = "run -p grebuloff-injector launch"
4 |
5 | [build]
6 | target = "x86_64-pc-windows-msvc"
7 | out-dir = "dist"
8 |
9 | [unstable]
10 | unstable-options = true
11 |
--------------------------------------------------------------------------------
/hlrt/src/renderer/src/App.tsx:
--------------------------------------------------------------------------------
1 | import './assets/App.css';
2 |
3 | function App(): JSX.Element {
4 | return (
5 |
6 |
Hello from Grebuloff!
7 |
8 | );
9 | }
10 |
11 | export default App;
12 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 | end_of_line = lf
10 |
11 | [*.{js,jsx,cjs,mjs,ts,tsx,cts,mts,json,yml,yaml}]
12 | indent_size = 2
13 |
--------------------------------------------------------------------------------
/loader/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "grebuloff-loader"
3 | version = "0.1.0"
4 | edition = "2021"
5 | build = "build.rs"
6 |
7 | [lib]
8 | crate-type = ["cdylib"]
9 | name = "winhttp"
10 |
11 | [dependencies]
12 | plthook = "0.2.2"
13 | windows = { workspace = true }
14 |
--------------------------------------------------------------------------------
/macros/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "grebuloff-macros"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [lib]
7 | proc-macro = true
8 |
9 | [dependencies]
10 | proc-macro2 = "1.0.60"
11 | quote = "1.0.28"
12 | syn = { version = "2", features = ["full"] }
13 | walkdir = "2.3.3"
14 |
--------------------------------------------------------------------------------
/hlrt/src/main/native/lib.rs:
--------------------------------------------------------------------------------
1 | use neon::prelude::*;
2 |
3 | fn hello(mut cx: FunctionContext) -> JsResult {
4 | Ok(cx.string("hello node"))
5 | }
6 |
7 | #[neon::main]
8 | fn main(mut cx: ModuleContext) -> NeonResult<()> {
9 | cx.export_function("hello", hello)?;
10 | Ok(())
11 | }
12 |
--------------------------------------------------------------------------------
/docs/sidebars.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
4 | const sidebars = {
5 | // By default, Docusaurus generates a sidebar from the docs folder structure
6 | main: [{ type: 'autogenerated', dirName: '.' }],
7 | };
8 |
9 | module.exports = sidebars;
10 |
--------------------------------------------------------------------------------
/injector/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "grebuloff-injector"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [dependencies]
7 | windows = { workspace = true }
8 | dll-syringe = { workspace = true, features = ["syringe", "rpc"] }
9 | clap = { version = "4.3.11", features = ["derive"] }
10 | sysinfo = "0.29.0"
11 |
--------------------------------------------------------------------------------
/docs/docs/architecture/llrt.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 2
3 | ---
4 |
5 | # Low-Level Runtime (LLRT)
6 |
7 | > **Language:** Rust
8 |
9 | The Low-Level Runtime (LLRT) is the entrypoint of Grebuloff to the game process.
10 | It is responsible for loading the [High-Level Runtime](/architecture/hlrt) into
11 | the game process.
12 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | /node_modules
3 |
4 | # Production
5 | /build
6 |
7 | # Generated files
8 | .docusaurus
9 | .cache-loader
10 |
11 | # Misc
12 | .DS_Store
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
--------------------------------------------------------------------------------
/hlrt/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": [
4 | "electron.vite.config.*",
5 | "src/main/**/*.{ts,tsx}",
6 | "src/preload/**/*.{ts,tsx}",
7 | ],
8 | "compilerOptions": {
9 | "composite": true,
10 | "types": [
11 | "node",
12 | "electron-vite/node"
13 | ],
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/hooking/shaders/vs.hlsl:
--------------------------------------------------------------------------------
1 | #include "common.hlsli"
2 |
3 | Interpolators main(uint vI : SV_VertexId)
4 | {
5 | Interpolators output;
6 |
7 | float2 texcoord = float2((vI << 1) & 2, vI & 2);
8 | output.TexCoord = texcoord;
9 | output.Position = float4(texcoord.x * 2 - 1, -texcoord.y * 2 + 1, 0, 1);
10 |
11 | return output;
12 | }
13 |
--------------------------------------------------------------------------------
/docs/docs/architecture/injector.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 1
3 | ---
4 |
5 | # Injector
6 |
7 | > **Language:** Rust
8 |
9 | The injector injects the [low-level runtime](/architecture/llrt) into the game process.
10 | It is one of the two supported ways to load Grebuloff, the other being through
11 | the [Dalamud support plugin](/architecture/dalamud).
12 |
--------------------------------------------------------------------------------
/docs/docs/architecture/libhlrt.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 3
3 | ---
4 |
5 | # High-Level Runtime Library (libhlrt)
6 |
7 | > **Language:** TypeScript
8 |
9 | The High-Level Runtime Library (libhlrt) is the core JavaScript library that is
10 | present in every V8 isolate. It provides the core functionality (such as logging)
11 | that is used by the [high-level runtime](/architecture/hlrt) and user scripts.
12 |
--------------------------------------------------------------------------------
/docs/docs/architecture/ui.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 5
3 | ---
4 |
5 | # User Interface (UI)
6 |
7 | > **Language:** TypeScript
8 | >
9 | > **Framework:** React
10 |
11 | The user interface of Grebuloff runs in the WebView2 instance that is spawned by
12 | the [low-level runtime](/architecture/llrt). It is responsible for rendering the
13 | UI of [high-level runtime](/architecture/hlrt) and any user add-ons.
14 |
--------------------------------------------------------------------------------
/rpc/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "grebuloff-rpc"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [dependencies]
7 | anyhow = { workspace = true }
8 | log = { workspace = true }
9 | tokio = { workspace = true }
10 | rmp = { workspace = true }
11 | rmp-serde = { workspace = true }
12 | serde = { workspace = true }
13 | serde_json = { workspace = true }
14 | bytes = { workspace = true }
15 | async-trait = "0.1.71"
16 |
--------------------------------------------------------------------------------
/hlrt/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "grebuloff-hlrt-native"
3 | version = "0.1.0"
4 | edition = "2021"
5 | exclude = ["*.node"]
6 |
7 | [lib]
8 | crate-type = ["cdylib"]
9 | path = "src/main/native/lib.rs"
10 |
11 | [dependencies]
12 | anyhow = { workspace = true }
13 | tokio = { workspace = true }
14 |
15 | [dependencies.neon]
16 | version = "0.10"
17 | default-features = false
18 | features = ["napi-6", "promise-api", "task-api", "channel-api"]
19 |
--------------------------------------------------------------------------------
/src/hooking/shaders/ps.hlsl:
--------------------------------------------------------------------------------
1 | #include "common.hlsli"
2 |
3 | float4 main(Interpolators In) : SV_Target0
4 | {
5 | float4 col = Texture.Sample(PointSampler, In.TexCoord);
6 |
7 | // Electron for Windows uses RGBA, and even though we can specify the texture as BGRA, it still
8 | // seems to perform faster when we swizzle the colour here instead of changing the D3D11_TEXTURE2D_DESC.
9 | return float4(col.b, col.g, col.r, col.a);
10 | }
11 |
--------------------------------------------------------------------------------
/dalamud/DalamudPackager.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/hlrt/tsconfig.web.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": [
4 | "src/renderer/src/env.d.ts",
5 | "src/renderer/src/**/*.{ts,tsx}",
6 | ],
7 | "compilerOptions": {
8 | "lib": [
9 | "ESNext",
10 | "DOM",
11 | "DOM.Iterable"
12 | ],
13 | "composite": true,
14 | "jsx": "react-jsx",
15 | "baseUrl": ".",
16 | "paths": {
17 | "@renderer/*": [
18 | "src/renderer/src/*"
19 | ]
20 | },
21 | }
22 | }
--------------------------------------------------------------------------------
/hlrt/src/renderer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/hlrt/src/renderer/src/assets/App.css:
--------------------------------------------------------------------------------
1 | .container {
2 | /* placeholder for testing */
3 | display: flex;
4 | justify-content: center;
5 | align-items: center;
6 | margin-top: 20%;
7 | font-size: 1.5em;
8 | }
9 |
10 | .spin {
11 | animation: spin 2s linear infinite;
12 | }
13 |
14 | @keyframes spin {
15 | 50% {
16 | transform: rotate(180deg);
17 | font-size: 3em;
18 | }
19 |
20 | 100% {
21 | transform: rotate(360deg);
22 | font-size: 1.5em;
23 | }
24 | }
--------------------------------------------------------------------------------
/docs/docs/architecture/hlrt.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 4
3 | ---
4 |
5 | # High-Level Runtime (HLRT)
6 |
7 | > **Language:** TypeScript
8 |
9 | The High-Level Runtime (HLRT) is the core of Grebuloff. It runs in a privileged
10 | V8 isolate, and is responsible for much of Grebuloff's core functionality,
11 | including plugin management.
12 |
13 | HLRT communicates with the [low-level runtime](/architecture/llrt) to handle
14 | game communications, and with the [UI](/architecture/ui) to provide UI services
15 | to addons.
16 |
--------------------------------------------------------------------------------
/hlrt/src/renderer/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './assets/index.css';
4 | import App from './App';
5 |
6 | declare global {
7 | interface Window {
8 | grebuloffUiMode: 'pipe' | 'no-pipe';
9 | }
10 | }
11 |
12 | if (window.grebuloffUiMode === 'no-pipe') {
13 | document.body.classList.add('no-pipe');
14 | }
15 |
16 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
17 |
18 |
19 | ,
20 | );
21 |
--------------------------------------------------------------------------------
/hlrt/electron.vite.config.ts:
--------------------------------------------------------------------------------
1 | import { resolve } from 'path';
2 | import { defineConfig, externalizeDepsPlugin, swcPlugin } from 'electron-vite';
3 | import react from '@vitejs/plugin-react';
4 |
5 | export default defineConfig({
6 | main: {
7 | plugins: [externalizeDepsPlugin(), swcPlugin()],
8 | },
9 | preload: {
10 | plugins: [externalizeDepsPlugin(), swcPlugin()],
11 | },
12 | renderer: {
13 | resolve: {
14 | alias: {
15 | '@renderer': resolve('src/renderer/src'),
16 | },
17 | },
18 | plugins: [react()],
19 | },
20 | });
21 |
--------------------------------------------------------------------------------
/hlrt/src/renderer/src/assets/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | overflow: hidden;
9 | background: transparent;
10 | color: red;
11 | }
12 |
13 | body.no-pipe {
14 | background: black !important;
15 | }
16 |
17 | code {
18 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
19 | monospace;
20 | }
21 |
--------------------------------------------------------------------------------
/docs/docs/architecture/dalamud.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 6
3 | ---
4 |
5 | # Dalamud Support Plugin
6 |
7 | > **Language:** C#
8 |
9 | The Dalamud Support Plugin is a Dalamud plugin that allows Grebuloff and Dalamud
10 | to run simultaneously. When the plugin is loaded by Dalamud, it will inject the
11 | [low-level runtime](/architecture/llrt) into the game process, starting the
12 | process of bootstrapping Grebuloff.
13 |
14 | When Grebuloff has been loaded through the support plugin, as opposed to through
15 | the [injector](/architecture/injector), function hooks will be handled through
16 | Dalamud, to avoid conflicts with other plugins.
17 |
--------------------------------------------------------------------------------
/hlrt/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2022",
4 | "module": "es2022",
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "experimentalDecorators": true,
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "composite": true,
16 | },
17 | "exclude": [
18 | "build.cjs",
19 | ],
20 | "references": [
21 | {
22 | "path": "./tsconfig.node.json"
23 | },
24 | {
25 | "path": "./tsconfig.web.json"
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/rpc/src/lib.rs:
--------------------------------------------------------------------------------
1 | use serde::{Deserialize, Serialize};
2 |
3 | pub mod ui;
4 |
5 | #[derive(Debug, PartialEq, Deserialize, Serialize)]
6 | #[serde(untagged)]
7 | pub enum RpcMessageDirection {
8 | /// Serverbound (client-to-server) communication.
9 | #[serde(skip_serializing)]
10 | Serverbound(RpcServerboundMessage),
11 |
12 | /// Clientbound (server-to-client) communication.
13 | #[serde(skip_deserializing)]
14 | Clientbound(RpcClientboundMessage),
15 | }
16 |
17 | #[derive(Debug, PartialEq, Deserialize)]
18 | pub enum RpcServerboundMessage {
19 | Ui(ui::UiRpcServerboundMessage),
20 | }
21 |
22 | #[derive(Debug, PartialEq, Serialize)]
23 | pub enum RpcClientboundMessage {
24 | Ui(ui::UiRpcClientboundMessage),
25 | }
26 |
--------------------------------------------------------------------------------
/hlrt/src/main/rpc/messages.ts:
--------------------------------------------------------------------------------
1 | import { Type } from 'class-transformer';
2 |
3 | export enum RpcMessageType {
4 | Resize = 'Resize',
5 | }
6 |
7 | export class RpcMessageResize {}
8 |
9 | export class PackedRpcMessage {
10 | public readonly type: RpcMessageType;
11 |
12 | @Type(() => Object, {
13 | discriminator: {
14 | property: 'type',
15 | subTypes: [{ value: RpcMessageResize, name: RpcMessageType.Resize }],
16 | },
17 | })
18 | public readonly data: any;
19 |
20 | constructor(type: RpcMessageType, data: any) {
21 | this.type = type;
22 | this.data = data;
23 | }
24 |
25 | into() {
26 | return {
27 | Ui: {
28 | [this.type.toString()]: this.data,
29 | },
30 | };
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .bonelessrc.json
2 |
3 | deps/cef_binary*
4 | deps/cef-sys/cef_binary*
5 | local/
6 | dist/
7 |
8 | # Rust
9 | target/
10 |
11 | # IntelliJ
12 | .idea/
13 | *.iml
14 |
15 | # VSCode
16 | .vscode/
17 |
18 | # macOS
19 | .DS_Store
20 | ._.*
21 |
22 | # .NET
23 | obj/
24 |
25 | # Logs
26 | logs
27 | *.log
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 | lerna-debug.log*
32 | .pnpm-debug.log*
33 | grebuloff*.log
34 |
35 | # Dependency directories
36 | node_modules/
37 |
38 | # TypeScript cache
39 | *.tsbuildinfo
40 |
41 | # Optional npm cache directory
42 | .npm
43 |
44 | # Optional eslint cache
45 | .eslintcache
46 |
47 | # dotenv environment variable files
48 | .env
49 | .env.development.local
50 | .env.test.local
51 | .env.production.local
52 | .env.local
53 |
--------------------------------------------------------------------------------
/src/hooking/wndproc.rs:
--------------------------------------------------------------------------------
1 | use super::create_function_hook;
2 | use crate::resolvers::resolve_signature;
3 | use anyhow::Result;
4 | use grebuloff_macros::function_hook;
5 | use log::debug;
6 | use windows::Win32::Foundation::{HWND, LPARAM, LRESULT, WPARAM};
7 |
8 | pub unsafe fn hook_wndproc() -> Result<()> {
9 | let wndproc_ptr = resolve_signature!("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 74 ?? B8");
10 | debug!("WndProc: {:p}", wndproc_ptr);
11 | create_function_hook!(wndproc, wndproc_ptr).enable()?;
12 |
13 | Ok(())
14 | }
15 |
16 | #[function_hook]
17 | unsafe fn wndproc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
18 | debug!(
19 | "WndProc invoked with: hwnd = {:?}, msg = {}, wparam = {:?}, lparam = {:?}",
20 | hwnd, msg, wparam, lparam
21 | );
22 | original.call(hwnd, msg, wparam, lparam)
23 | }
24 |
--------------------------------------------------------------------------------
/dalamud/grebuloff-dalamud.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grebuloff.Dalamud", "Grebuloff.Dalamud.csproj", "{726E199D-0E6E-4838-A595-222CC63D49F4}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Any CPU = Debug|Any CPU
8 | Release|Any CPU = Release|Any CPU
9 | EndGlobalSection
10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
11 | {726E199D-0E6E-4838-A595-222CC63D49F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
12 | {726E199D-0E6E-4838-A595-222CC63D49F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
13 | {726E199D-0E6E-4838-A595-222CC63D49F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
14 | {726E199D-0E6E-4838-A595-222CC63D49F4}.Release|Any CPU.Build.0 = Release|Any CPU
15 | EndGlobalSection
16 | EndGlobal
17 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Website
2 |
3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
4 |
5 | ### Installation
6 |
7 | ```
8 | $ pnpm
9 | ```
10 |
11 | ### Local Development
12 |
13 | ```
14 | $ pnpm start
15 | ```
16 |
17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
18 |
19 | ### Build
20 |
21 | ```
22 | $ pnpm build
23 | ```
24 |
25 | This command generates static content into the `build` directory and can be served using any static contents hosting service.
26 |
27 | ### Deployment
28 |
29 | Using SSH:
30 |
31 | ```
32 | $ USE_SSH=true pnpm deploy
33 | ```
34 |
35 | Not using SSH:
36 |
37 | ```
38 | $ GIT_USER= pnpm deploy
39 | ```
40 |
41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
42 |
--------------------------------------------------------------------------------
/dalamud/Plugin.cs:
--------------------------------------------------------------------------------
1 | using Dalamud.Game;
2 | using Dalamud.Plugin;
3 |
4 | namespace Grebuloff.Dalamud;
5 |
6 | public sealed class Plugin : IDalamudPlugin
7 | {
8 | public string Name => "Grebuloff Compatibility Layer";
9 |
10 | public DalamudPluginInterface PluginInterface { get; private set; }
11 | public Framework Framework { get; private set; }
12 |
13 | public Plugin(DalamudPluginInterface pluginInterface, Framework framework)
14 | {
15 | PluginInterface = pluginInterface;
16 | Framework = framework;
17 |
18 | PluginInterface.UiBuilder.Draw += this.DrawUI;
19 | Framework.Update += OnFrameworkUpdate;
20 | }
21 |
22 | private void OnFrameworkUpdate(Framework framework)
23 | {
24 | }
25 |
26 | private void DrawUI()
27 | {
28 |
29 | }
30 |
31 | public void Dispose()
32 | {
33 | Framework.Update -= OnFrameworkUpdate;
34 | PluginInterface.UiBuilder.Draw -= this.DrawUI;
35 | }
36 | }
--------------------------------------------------------------------------------
/docs/custom.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Any CSS included here will be global. The classic template
3 | * bundles Infima by default. Infima is a CSS framework designed to
4 | * work well for content-centric websites.
5 | */
6 |
7 | /* You can override the default Infima variables here. */
8 | :root {
9 | --ifm-color-primary: #2e8555;
10 | --ifm-color-primary-dark: #29784c;
11 | --ifm-color-primary-darker: #277148;
12 | --ifm-color-primary-darkest: #205d3b;
13 | --ifm-color-primary-light: #33925d;
14 | --ifm-color-primary-lighter: #359962;
15 | --ifm-color-primary-lightest: #3cad6e;
16 | --ifm-code-font-size: 95%;
17 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
18 | }
19 |
20 | /* For readability concerns, you should choose a lighter palette in dark mode. */
21 | [data-theme='dark'] {
22 | --ifm-color-primary: #25c2a0;
23 | --ifm-color-primary-dark: #21af90;
24 | --ifm-color-primary-darker: #1fa588;
25 | --ifm-color-primary-darkest: #1a8870;
26 | --ifm-color-primary-light: #29d5b0;
27 | --ifm-color-primary-lighter: #32d8b4;
28 | --ifm-color-primary-lightest: #4fddbf;
29 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
30 | }
31 |
--------------------------------------------------------------------------------
/dalamud/Channel.cs:
--------------------------------------------------------------------------------
1 | using System.IO.Pipes;
2 |
3 | namespace Grebuloff.Dalamud;
4 |
5 | public class Channel : IDisposable
6 | {
7 | public string Name { get; }
8 | private readonly CancellationTokenSource _cts = new();
9 | private readonly NamedPipeServerStream _server;
10 | private StreamWriter? _writer;
11 | private StreamReader? _reader;
12 |
13 | public Channel()
14 | {
15 | // generate a random UUID
16 | Name = $"grebuloff-dalamud-{Guid.NewGuid()}";
17 | _server = new NamedPipeServerStream(
18 | Name,
19 | PipeDirection.InOut,
20 | 1,
21 | PipeTransmissionMode.Message,
22 | PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly
23 | );
24 | }
25 |
26 | private async void AwaitConnection()
27 | {
28 | await _server.WaitForConnectionAsync(_cts.Token);
29 | _writer = new StreamWriter(_server);
30 | _reader = new StreamReader(_server);
31 | }
32 |
33 | public void Dispose()
34 | {
35 | _cts.Cancel();
36 | _reader?.Dispose();
37 | _writer?.Dispose();
38 | _server.Dispose();
39 | }
40 | }
--------------------------------------------------------------------------------
/hlrt/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | browser: true,
5 | commonjs: true,
6 | es6: true,
7 | node: true,
8 | },
9 | parser: '@typescript-eslint/parser',
10 | parserOptions: {
11 | ecmaFeatures: {
12 | jsx: true,
13 | },
14 | sourceType: 'module',
15 | ecmaVersion: 2021,
16 | },
17 | plugins: ['@typescript-eslint'],
18 | extends: [
19 | 'eslint:recommended',
20 | 'plugin:react/recommended',
21 | 'plugin:react/jsx-runtime',
22 | 'plugin:@typescript-eslint/recommended',
23 | 'plugin:@typescript-eslint/eslint-recommended',
24 | 'plugin:prettier/recommended',
25 | ],
26 | rules: {
27 | '@typescript-eslint/explicit-module-boundary-types': 'off',
28 | '@typescript-eslint/no-empty-function': [
29 | 'error',
30 | { allow: ['arrowFunctions'] },
31 | ],
32 | '@typescript-eslint/no-non-null-assertion': 'off',
33 | '@typescript-eslint/no-var-requires': 'off',
34 | },
35 | overrides: [
36 | {
37 | files: ['*.js'],
38 | rules: {
39 | '@typescript-eslint/explicit-function-return-type': 'off',
40 | },
41 | },
42 | ],
43 | };
44 |
--------------------------------------------------------------------------------
/hlrt/patches/build-if-changed@1.5.5.patch:
--------------------------------------------------------------------------------
1 | diff --git a/CHANGELOG.md b/CHANGELOG.md
2 | deleted file mode 100644
3 | index cb8bc80d7e68e5704d7d7e43529bc608c2902728..0000000000000000000000000000000000000000
4 | diff --git a/lib/gitignore.js b/lib/gitignore.js
5 | index 15c2c620b28ba9ea907d833e511ebfe9047d9f0e..eef9128dfa7535bd56a0f5922dc5c001e9814bc7 100644
6 | --- a/lib/gitignore.js
7 | +++ b/lib/gitignore.js
8 | @@ -20,6 +20,7 @@ class GitIgnore {
9 | this.matchRootGlobs = recrawl_1.createMatcher(rootGlobs);
10 | }
11 | test(file, name) {
12 | + return false;
13 | if (!path_1.isAbsolute(file)) {
14 | throw Error('Expected an absolute path');
15 | }
16 | diff --git a/lib/index.js b/lib/index.js
17 | index 5e2615dae3c000e72ed93613efb9279aabee42f2..f441e21a1e0d7dbaa98915e3b95d4dce4debbafb 100644
18 | --- a/lib/index.js
19 | +++ b/lib/index.js
20 | @@ -195,7 +195,7 @@ function getLines(data) {
21 | .split(/\r?\n/);
22 | }
23 | function getRunner(root) {
24 | - return fs.isFile(path_1.join(root, 'package-lock.json')) ? 'npm' : 'yarn';
25 | + return 'pnpm';
26 | }
27 | function filterTruthy(changed) {
28 | return changed.filter(Boolean);
--------------------------------------------------------------------------------
/src/dalamud.rs:
--------------------------------------------------------------------------------
1 | use log::info;
2 | use std::sync::Mutex;
3 | use std::time::Duration;
4 | use tokio::net::windows::named_pipe::{ClientOptions, NamedPipeClient};
5 | use tokio::time;
6 | use windows::Win32::Foundation::ERROR_PIPE_BUSY;
7 |
8 | #[derive(Debug)]
9 | pub struct DalamudPipe {
10 | pipe_name: String,
11 | pipe_client: Mutex