@adiholick/nvstudio-mcp 1.1.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,97 @@
1
+ local HttpService = game:GetService("HttpService")
2
+
3
+ return function(targetInstance, data, ctx, targetPath)
4
+ if not targetInstance:IsA("LuaSourceContainer") then
5
+ return { status = "error", error = "Target BUKAN Script (ClassName: " .. targetInstance.ClassName .. ")." }
6
+ end
7
+
8
+ local payload = nil
9
+ pcall(function()
10
+ payload = HttpService:JSONDecode(data)
11
+ end)
12
+
13
+ if not payload then
14
+ return { status = "error", error = "Payload data harus berupa JSON valid." }
15
+ end
16
+
17
+ local currentSource = targetInstance.Source
18
+ local newSource = currentSource
19
+ local affectedLines = 0
20
+
21
+ -- Mode 1: Search & Replace Exact Chunk
22
+ if payload.target_content and payload.replacement_content then
23
+ local targetContent = payload.target_content
24
+ local replacementContent = payload.replacement_content
25
+ local allowMultiple = payload.allow_multiple or false
26
+
27
+ -- Escape magic characters for string.gsub if needed, or use string.find manually.
28
+ -- string.gsub doesn't do plain text replacement directly without escaping.
29
+ -- We'll write a plain text replace function.
30
+
31
+ local function plainReplace(str, pattern, repl, max)
32
+ local res = ""
33
+ local startIdx = 1
34
+ local count = 0
35
+ while true do
36
+ if max and count >= max then break end
37
+ local findStart, findEnd = string.find(str, pattern, startIdx, true) -- true for plain match
38
+ if not findStart then break end
39
+
40
+ res = res .. string.sub(str, startIdx, findStart - 1) .. repl
41
+ startIdx = findEnd + 1
42
+ count = count + 1
43
+ end
44
+ res = res .. string.sub(str, startIdx)
45
+ return res, count
46
+ end
47
+
48
+ local _, occurrences = plainReplace(currentSource, targetContent, replacementContent)
49
+
50
+ if occurrences == 0 then
51
+ return { status = "error", error = "target_content tidak ditemukan di dalam script." }
52
+ elseif occurrences > 1 and not allowMultiple then
53
+ return { status = "error", error = "target_content ditemukan " .. occurrences .. " kali. Tolong sertakan baris konteks lebih banyak agar unik, atau set allow_multiple = true." }
54
+ end
55
+
56
+ newSource, affectedLines = plainReplace(currentSource, targetContent, replacementContent)
57
+ affectedLines = affectedLines -- not exact line count, but occurrences count
58
+
59
+ -- Mode 2: Line Range Replace
60
+ elseif payload.start_line and payload.end_line and payload.replacement_content then
61
+ local lines = string.split(currentSource, "\n")
62
+ local startLine = tonumber(payload.start_line)
63
+ local endLine = tonumber(payload.end_line)
64
+
65
+ if not startLine or not endLine or startLine < 1 or endLine > #lines or startLine > endLine then
66
+ return { status = "error", error = "Range baris tidak valid. Jumlah baris script: " .. #lines }
67
+ end
68
+
69
+ local newLines = {}
70
+ for i = 1, startLine - 1 do
71
+ table.insert(newLines, lines[i])
72
+ end
73
+
74
+ table.insert(newLines, payload.replacement_content)
75
+
76
+ for i = endLine + 1, #lines do
77
+ table.insert(newLines, lines[i])
78
+ end
79
+
80
+ newSource = table.concat(newLines, "\n")
81
+ affectedLines = (endLine - startLine) + 1
82
+ else
83
+ return { status = "error", error = "Payload tidak lengkap. Butuh (target_content & replacement_content) atau (start_line, end_line & replacement_content)." }
84
+ end
85
+
86
+ -- Simpan backup snapshot sebelum mengaplikasikan patch
87
+ ctx.scriptHistory[targetPath] = currentSource
88
+
89
+ -- Terapkan perubahan
90
+ targetInstance.Source = newSource
91
+
92
+ return {
93
+ status = "success",
94
+ result = "Patch berhasil diterapkan pada '" .. targetInstance.Name .. "'. Perubahan diaplikasikan.",
95
+ affected_lines = affectedLines
96
+ }
97
+ end