linjector-luau-script-ide
Open-source Luau/Lua script IDE and executor built as a Windows Forms C# application with Monaco editor integration
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o linjector-luau-script-ide.zip https://jpskill.com/download/22998.zip && unzip -o linjector-luau-script-ide.zip && rm linjector-luau-script-ide.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/22998.zip -OutFile "$d\linjector-luau-script-ide.zip"; Expand-Archive "$d\linjector-luau-script-ide.zip" -DestinationPath $d -Force; ri "$d\linjector-luau-script-ide.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
linjector-luau-script-ide.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
linjector-luau-script-ideフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Claude が読む原文 SKILL.md(中身を展開)
この本文は AI(Claude)が読むための原文(英語または中国語)です。日本語訳は順次追加中。
LInjector Luau Script IDE
Skill by ara.so — Daily 2026 Skills collection.
LInjector is an open-source Luau/Lua script IDE and executor built as a Windows Forms application in C# (.NET Framework 4.8, 32-bit). It features the Monaco editor (the same editor powering VS Code) with Luau syntax highlighting, an optimized multi-tab system, and DLL injection capabilities targeting the Roblox UWP client.
Important Note (2026): The UWP Version is patched due to Hyperion/Byfron anti-cheat. You can still build, modify, and extend LInjector by providing your own working DLL or injection method.
Project Structure
LInjector/
├── LInjector.sln # Visual Studio solution
├── LInjector/
│ ├── LInjector.csproj # Project file (.NET 4.8, x86)
│ ├── Forms/ # Windows Forms UI
│ │ ├── MainForm.cs # Main application window
│ │ └── *.cs # Other form files
│ ├── Classes/ # Core logic classes
│ │ ├── Injector.cs # DLL injection logic
│ │ ├── TabSystem.cs # Optimized tab management
│ │ └── *.cs
│ ├── Monaco/ # Monaco editor web assets
│ │ ├── index.html # Editor host page
│ │ └── *.js # Monaco JS files
│ └── Resources/ # Embedded resources
Build Requirements
- Visual Studio 2022
- .NET Framework 4.8 SDK
- Target Platform: x86 (32-bit)
- Configuration: Release
How to Build
# 1. Clone the repository
git clone https://github.com/WeritoP/LInjector-FORKED-
cd LInjector-FORKED-
# 2. Open in Visual Studio 2022
start LInjector.sln
# 3. Set build configuration in VS:
# Configuration: Release
# Platform: x86
# 4. Build via keyboard shortcut
# CTRL + SHIFT + B
# OR via CLI with MSBuild
msbuild LInjector.sln /p:Configuration=Release /p:Platform=x86
Important: Always compile before editing Forms. If you open a Form before compiling, Visual Studio's designer will fail. If this happens, restart Visual Studio.
Monaco Editor Integration
LInjector embeds Monaco in a WebBrowser or WebView2 control. The editor is hosted in a local HTML file.
Accessing the Monaco Editor from C
// In your Form class — get script content from Monaco
private string GetEditorContent()
{
// Execute JavaScript to retrieve editor value
object result = webBrowser.Document.InvokeScript(
"eval",
new object[] { "monaco.editor.getModels()[0].getValue()" }
);
return result?.ToString() ?? string.Empty;
}
// Set content in Monaco editor
private void SetEditorContent(string script)
{
string escaped = script
.Replace("\\", "\\\\")
.Replace("'", "\\'")
.Replace("\n", "\\n")
.Replace("\r", "\\r");
webBrowser.Document.InvokeScript(
"eval",
new object[] { $"monaco.editor.getModels()[0].setValue('{escaped}')" }
);
}
Monaco Editor Host HTML (Monaco/index.html pattern)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
html, body, #container {
width: 100%; height: 100%;
margin: 0; padding: 0;
overflow: hidden;
background: #1e1e1e;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="monaco/min/vs/loader.js"></script>
<script>
require.config({ paths: { 'vs': 'monaco/min/vs' } });
require(['vs/editor/editor.main'], function () {
window.editor = monaco.editor.create(
document.getElementById('container'), {
value: '-- LInjector Script\n',
language: 'lua',
theme: 'vs-dark',
fontSize: 14,
automaticLayout: true,
minimap: { enabled: false },
scrollBeyondLastLine: false
}
);
});
// Helper functions callable from C#
function getScript() {
return window.editor.getValue();
}
function setScript(val) {
window.editor.setValue(val);
}
function clearScript() {
window.editor.setValue('');
}
</script>
</body>
</html>
Tab System
LInjector's tab system is optimized to cap RAM usage at ~1 GB even with 40+ tabs open.
// TabSystem.cs — Example pattern for managing script tabs
public class ScriptTab
{
public string Name { get; set; }
public string Content { get; set; }
public TabPage TabPage { get; set; }
public ScriptTab(string name, string content = "")
{
Name = name;
Content = content;
}
}
public class TabManager
{
private readonly List<ScriptTab> _tabs = new List<ScriptTab>();
private readonly TabControl _tabControl;
private int _activeIndex = 0;
public TabManager(TabControl tabControl)
{
_tabControl = tabControl;
}
// Add a new script tab
public void AddTab(string name = null)
{
int tabNumber = _tabs.Count + 1;
string tabName = name ?? $"Script {tabNumber}";
var tab = new ScriptTab(tabName);
var tabPage = new TabPage(tabName);
tab.TabPage = tabPage;
_tabs.Add(tab);
_tabControl.TabPages.Add(tabPage);
_tabControl.SelectedTab = tabPage;
}
// Remove tab by index
public void RemoveTab(int index)
{
if (index < 0 || index >= _tabs.Count) return;
_tabControl.TabPages.Remove(_tabs[index].TabPage);
_tabs.RemoveAt(index);
}
// Save current tab content before switching
public void SaveCurrentTabContent(string content)
{
if (_activeIndex >= 0 && _activeIndex < _tabs.Count)
_tabs[_activeIndex].Content = content;
}
// Get content for a tab
public string GetTabContent(int index)
{
if (index < 0 || index >= _tabs.Count) return string.Empty;
return _tabs[index].Content;
}
}
DLL Injection (Custom Integration)
Since the original injection target is patched, here is the pattern used to plug in your own DLL:
// Classes/Injector.cs — Pattern for DLL injection
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
public class Injector
{
[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(int access, bool inherit, int processId);
[DllImport("kernel32.dll")]
private static extern IntPtr VirtualAllocEx(
IntPtr hProcess, IntPtr lpAddress,
uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
private static extern bool WriteProcessMemory(
IntPtr hProcess, IntPtr lpBaseAddress,
byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
private static extern IntPtr CreateRemoteThread(
IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize,
IntPtr lpStartAddress, IntPtr lpParameter,
uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
private const int PROCESS_ALL_ACCESS = 0x1F0FFF;
private const uint MEM_COMMIT = 0x1000;
private const uint MEM_RESERVE = 0x2000;
private const uint PAGE_READWRITE = 0x04;
/// <summary>
/// Inject a DLL into a target process by name.
/// Returns true on success.
/// </summary>
public static bool InjectDll(string processName, string dllPath)
{
if (!File.Exists(dllPath))
throw new FileNotFoundException($"DLL not found: {dllPath}");
Process[] procs = Process.GetProcessesByName(processName);
if (procs.Length == 0)
throw new Exception($"Process '{processName}' not found.");
Process target = procs[0];
IntPtr hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, target.Id);
if (hProcess == IntPtr.Zero)
throw new Exception("Failed to open process.");
byte[] dllBytes = System.Text.Encoding.ASCII.GetBytes(dllPath + "\0");
IntPtr allocMem = VirtualAllocEx(
hProcess, IntPtr.Zero, (uint)dllBytes.Length,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (allocMem == IntPtr.Zero)
throw new Exception("Memory allocation failed.");
WriteProcessMemory(hProcess, allocMem, dllBytes,
(uint)dllBytes.Length, out _);
IntPtr loadLibAddr = GetProcAddress(
GetModuleHandle("kernel32.dll"), "LoadLibraryA");
IntPtr thread = CreateRemoteThread(
hProcess, IntPtr.Zero, 0,
loadLibAddr, allocMem, 0, IntPtr.Zero);
return thread != IntPtr.Zero;
}
}
Using the Injector from UI
// In MainForm.cs — Inject button click handler
private async void btnInject_Click(object sender, EventArgs e)
{
string dllPath = Path.Combine(
Application.StartupPath, "Modules", "your_dll.dll");
try
{
bool success = await Task.Run(() =>
Injector.InjectDll("RobloxPlayerBeta", dllPath));
lblStatus.Text = success
? "✔ Injected successfully"
: "✘ Injection failed";
}
catch (Exception ex)
{
MessageBox.Show($"Error: {ex.Message}", "LInjector",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Script Execution Pattern
// Execute the current script via the injected DLL's named pipe or HTTP endpoint
private async void btnExecute_Click(object sender, EventArgs e)
{
string script = GetEditorContent();
if (string.IsNullOrWhiteSpace(script)) return;
try
{
await ExecuteScriptAsync(script);
lblStatus.Text = "Script executed.";
}
catch (Exception ex)
{
lblStatus.Text = $"Error: {ex.Message}";
}
}
private async Task ExecuteScriptAsync(string script)
{
// Example: communicate with injected DLL via named pipe
using var pipe = new System.IO.Pipes.NamedPipeClientStream(
".", "LInjectorPipe",
System.IO.Pipes.PipeDirection.Out);
await pipe.ConnectAsync(timeoutMilliseconds: 3000);
byte[] data = System.Text.Encoding.UTF8.GetBytes(script);
await pipe.WriteAsync(data, 0, data.Length);
}
Script File Management
// Save script to file
private void SaveScript(string content, string filePath = null)
{
if (filePath == null)
{
using var sfd = new SaveFileDialog
{
Filter = "Lua Files (*.lua)|*.lua|Text Files (*.txt)|*.txt|All Files (*.*)|*.*",
DefaultExt = "lua",
FileName = "script"
};
if (sfd.ShowDialog() != DialogResult.OK) return;
filePath = sfd.FileName;
}
File.WriteAllText(filePath, content, System.Text.Encoding.UTF8);
}
// Load script from file
private string LoadScript()
{
using var ofd = new OpenFileDialog
{
Filter = "Lua Files (*.lua)|*.lua|Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
};
if (ofd.ShowDialog() != DialogResult.OK) return null;
return File.ReadAllText(ofd.FileName, System.Text.Encoding.UTF8);
}
Configuration Pattern
LInjector uses app settings for persistent configuration:
// Reading/writing settings (App.config / user settings)
// In Settings.settings, add keys: Theme, FontSize, AutoInject
// Read
string theme = Properties.Settings.Default.Theme ?? "vs-dark";
int fontSize = Properties.Settings.Default.FontSize > 0
? Properties.Settings.Default.FontSize : 14;
// Write and save
Properties.Settings.Default.Theme = "vs-dark";
Properties.Settings.Default.FontSize = 16;
Properties.Settings.Default.Save();
// Apply theme to Monaco from C#
private void ApplyEditorTheme(string theme)
{
webBrowser.Document.InvokeScript(
"eval",
new object[] { $"monaco.editor.setTheme('{theme}')" }
);
}
Common Customization Patterns
Change Target Process
// Replace "RobloxPlayerBeta" with your target process name
private const string TARGET_PROCESS = "RobloxPlayerBeta";
// or for UWP:
// private const string TARGET_PROCESS = "Windows10Universal";
Add Custom Luau Autocomplete to Monaco
// In Monaco/index.html — register Luau-specific completions
monaco.languages.registerCompletionItemProvider('lua', {
provideCompletionItems: function(model, position) {
return {
suggestions: [
{
label: 'game',
kind: monaco.languages.CompletionItemKind.Variable,
insertText: 'game',
documentation: 'The root DataModel instance'
},
{
label: 'workspace',
kind: monaco.languages.CompletionItemKind.Variable,
insertText: 'workspace',
documentation: 'Alias for game.Workspace'
},
{
label: 'loadstring',
kind: monaco.languages.CompletionItemKind.Function,
insertText: 'loadstring(${1:source})()',
insertTextRules:
monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: 'Load and execute a string as Lua code'
}
]
};
}
});
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Forms designer blank/broken | Compiled before opening form | Compile first (CTRL+SHIFT+B), then restart VS |
msbuild not found |
MSBuild not in PATH | Use VS Developer Command Prompt |
| Injection returns false | Process not found or access denied | Run as Administrator; verify process name |
| Monaco editor blank | WebBrowser control needs IE11 emulation | Add registry key for IE emulation (see below) |
| DLL not found error | DLL missing from Modules/ folder |
Place your DLL in the output Modules/ directory |
Fix Monaco Blank in WebBrowser Control
Add this to your app startup (requires running as admin once, or via installer):
// Force IE11 rendering mode for WebBrowser control
private static void SetWebBrowserEmulation()
{
string appName = Path.GetFileName(Application.ExecutablePath);
using var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
@"SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",
writable: true);
key?.SetValue(appName, 11001, Microsoft.Win32.RegistryValueKind.DWord);
}
// Call SetWebBrowserEmulation() in Program.cs before Application.Run()
Verify Target Process is Running
public static bool IsProcessRunning(string name)
=> Process.GetProcessesByName(name).Length > 0;
// Usage
if (!IsProcessRunning("RobloxPlayerBeta"))
{
MessageBox.Show("Please launch Roblox before injecting.",
"LInjector", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
Key Facts
- Language: C# / .NET Framework 4.8
- Platform: Windows, x86 (32-bit) only
- Editor: Monaco (VS Code engine) with Lua/Luau syntax
- Injection speed: ~300ms (when working)
- Tab RAM cap: ~1 GB for 40+ tabs
- License: MIT
- Status (2026): UWP target patched by Hyperion; source remains functional for custom DLL targets