feat(rbxl): XML-������ ������ .rbxl + Day/Night + Tool/Mouse/Backpack flow #38

Closed
min wants to merge 39 commits from feat/rbxl-xml-parser-import into main
Showing only changes of commit 59d0d86811 - Show all commits

View File

@ -241,9 +241,27 @@ function makeInstanceMethods() {
return _instanceMethods; return _instanceMethods;
} }
// Создаёт stub-signal который ничего не делает — для unknown свойств Instance
// которые скрипты пытаются использовать как сигнал (script.Parent.Selected:Connect).
function makeStubSignal() {
const sig = makeSignal();
// Помечаем чтобы знать что это stub (для возможной отладки)
sig.__stub = true;
return sig;
}
// Эвристика: какие имена свойств вероятно сигналы?
// В Roblox сигналы заканчиваются на: Changed, Added, Removed, Began, Ended,
// Clicked, Activated, Touched, Selected, Deselected, Equipped, Unequipped, и т.д.
function isProbablySignalName(prop) {
if (typeof prop !== 'string') return false;
return /^(Mouse|Touch|Input|Render|Step|Heart|Render|On|Char|Player|Selected|Deselect|Equipped|Unequipped|Activated|Click|Changed|Added|Removed|Began|Ended|Died|Spawned|Reached|Loaded|Hover)/.test(prop)
|| /(Changed|Added|Removed|Began|Ended|Clicked|Activated|Touched|Died|Loaded|Hover|Connect|Event|Signal|Reached)$/.test(prop);
}
function newInstance(className, name) { function newInstance(className, name) {
const m = makeInstanceMethods(); const m = makeInstanceMethods();
return { const target = {
ClassName: className || 'Instance', ClassName: className || 'Instance',
Name: name || className || 'Instance', Name: name || className || 'Instance',
Parent: undefined, Parent: undefined,
@ -269,6 +287,35 @@ function newInstance(className, name) {
SetAttribute: m.SetAttribute, SetAttribute: m.SetAttribute,
GetPropertyChangedSignal: m.GetPropertyChangedSignal, GetPropertyChangedSignal: m.GetPropertyChangedSignal,
}; };
// Proxy: для unknown свойств возвращаем stub чтобы скрипты не падали.
return new Proxy(target, {
get(t, prop) {
if (prop in t) return t[prop];
if (typeof prop !== 'string') return undefined;
// Системные/wasmoon-внутренние ключи — undefined чтобы wasmoon не путался
if (prop === 'then' || prop === 'catch' || prop === 'toJSON' ||
prop === Symbol.toPrimitive || prop.startsWith('__')) {
return undefined;
}
if (isProbablySignalName(prop)) {
const stub = makeStubSignal();
t[prop] = stub;
return stub;
}
// Иначе — child stub (Folder) который тоже выживет на чтении свойств
// и может иметь свои дочерние stub'ы. Cache в target чтобы тот же ссылочно.
const childStub = newInstance('Folder', prop);
t[prop] = childStub;
return childStub;
},
set(t, prop, value) {
t[prop] = value;
return true;
},
has(t, prop) {
return prop in t || (typeof prop === 'string' && !prop.startsWith('__'));
},
});
} }
/** /**