[v.1.0.1] InstancesInfo, simple API for ReflectionService

As you know Roblox just released ReflectionService, that allow you to get Instance(s) information, such as:

  • Instance superclass
  • Instance properties
  • Is instance/propertie deprecated
  • Propertie write/read security capabilities
  • Propertie value type
  • Etc

This allowing you to get all Information without using HttpService.


:cross_mark: What ReflectionService currently lacks:

  • Instance methods
  • Instance signals

πŸ”¨ Features

  • Simple API
  • Server/Client/Plugin RunContext support
  • Typecasted (Including function description)

Icon Link Note
ModuleScript Module Get latest version
Github Open source code

:speech_balloon: Feel free to give feedback :speech_balloon:

1 Like

Nice, heres mine I made the other day.

--!strict
local ReflectionService = game:GetService('ReflectionService')

local reflection = {}
local cachedProperties = {}
local cachedClasses = {}
local classes = nil

function reflection.getValidPropertiesFromClass(class : string, filter : ReflectionMemberFilter?) : {
		Name: string,
		Serialized: boolean,
		Type: ReflectionType,
		ContentType: Enum.AssetType?,
		Display: {
			Category: string,
			DepreciationMessage: string?,
			LayoutOrder: number,
		}?,
		Permits: {
			Read: SecurityCapabilities?,
			ReadParallel: SecurityCapabilities?,
			Write: SecurityCapabilities?,
			WriteParallel: SecurityCapabilities?,
		},
	}
	
	local instance = Instance.new(class)
	local properties = reflection.getPropertiesFromClass(class, filter, false)
	
	local valid = {}
	
	for _, v : any in properties do
		local succ, result = pcall(function()
			return instance[v.Name]
		end)
		
		if succ then
			table.insert(valid, v)
		end
	end
	
	instance:Destroy()
	
	return valid :: any
end

function reflection.getPropertiesFromClass(class : string, filter : ReflectionMemberFilter?, validOnly : boolean?) : {
		Name: string,
		Serialized: boolean,
		Type: ReflectionType,
		ContentType: Enum.AssetType?,
		Display: {
			Category: string,
			DepreciationMessage: string?,
			LayoutOrder: number,
		}?,
		Permits: {
			Read: SecurityCapabilities?,
			ReadParallel: SecurityCapabilities?,
			Write: SecurityCapabilities?,
			WriteParallel: SecurityCapabilities?,
		},
	}
	
	if validOnly ~= nil and validOnly == true then
		return reflection.getValidPropertiesFromClass(class, filter)
	end
	
	if cachedProperties[class] and filter == nil then
		return cachedProperties[class]
	end
	
	if filter ~= nil then
		return ReflectionService:GetPropertiesOfClass(class, filter)
	end

	cachedProperties[class] = ReflectionService:GetPropertiesOfClass(class)
	return cachedProperties[class]
end

function reflection.getProperties(instance : Instance, filter : ReflectionMemberFilter?, validOnly : boolean?) : {
		Name: string,
		Serialized: boolean,
		Type: ReflectionType,
		ContentType: Enum.AssetType?,
		Display: {
			Category: string,
			DepreciationMessage: string?,
			LayoutOrder: number,
		}?,
		Permits: {
			Read: SecurityCapabilities?,
			ReadParallel: SecurityCapabilities?,
			Write: SecurityCapabilities?,
			WriteParallel: SecurityCapabilities?,
		},
	}
	
	return reflection.getPropertiesFromClass(instance.ClassName, filter, validOnly)
end

function reflection.getPropertyNamesFromClass(class : string, filter : ReflectionMemberFilter?, validOnly : boolean?) : {string}
	local properties = reflection.getPropertiesFromClass(class, filter, validOnly)

	local propNames = {}

	for _, v : any in properties do
		table.insert(propNames, v.Name)
	end

	return propNames
end

function reflection.getPropertyNames(instance : Instance, filter : ReflectionMemberFilter?, validOnly : boolean?) : {string}
	local class = instance.ClassName
	
	return reflection.getPropertyNamesFromClass(class, filter, validOnly)
end

function reflection.getClasses(filter : ReflectionClassFilter?) :{
		[number] : {
			Name: string,
			Superclass: string?,
			Subclasses: {string},
			Display: {
				Category: string,
				DeprecationMessage: string?,
			}?,
			Permits: {
				GetService: SecurityCapabilities?,
				New: SecurityCapabilities?,
			}
		}
	}
	
	if filter == nil then
		if classes then
			return classes
		end
		
		classes = ReflectionService:GetClasses()
		return classes
	end
	
	return ReflectionService:GetClasses(filter)
end

function reflection.getClass(className : string, filter : ReflectionClassFilter?) : {
		Name: string,
		Superclass: string?,
		Subclasses: {string},
		Display: {
			Category: string,
			DeprecationMessage: string?,
		}?,
		Permits: {
			GetService: SecurityCapabilities?,
			New: SecurityCapabilities?,
		}
	}
	
	if cachedClasses[className] and filter == nil then
		return cachedClasses[className]
	end
	
	if filter then
		return ReflectionService:GetClass(className, filter)
	end
	
	cachedClasses[className] = ReflectionService:GetClass(className)
	return cachedClasses[className]
end

function reflection.getClassFromInstance(instance : Instance, filter : ReflectionClassFilter?) : {
		Name: string,
		Superclass: string?,
		Subclasses: {string},
		Display: {
			Category: string,
			DeprecationMessage: string?,
		}?,
		Permits: {
			GetService: SecurityCapabilities?,
			New: SecurityCapabilities?,
		}
	}
	
	local className = instance.ClassName
	
	return reflection.getClass(className, filter)
end

local reflectionInstance = {}
type reflectionInstance = {
	getProperties : (reflectionInstance, filter : ReflectionMemberFilter?, validOnly : boolean?) -> {
		Name: string,
		Serialized: boolean,
		Type: ReflectionType,
		ContentType: Enum.AssetType?,
		Display: {
			Category: string,
			DepreciationMessage: string?,
			LayoutOrder: number,
		}?,
		Permits: {
			Read: SecurityCapabilities?,
			ReadParallel: SecurityCapabilities?,
			Write: SecurityCapabilities?,
			WriteParallel: SecurityCapabilities?,
		},
	},
	
	getPropertyNames : (reflectionInstance, filter : ReflectionMemberFilter?, validOnly : boolean?) -> {string}
}

function reflection.new(instance : Instance) : reflectionInstance & any
	return setmetatable({inst = instance}, {__index = reflectionInstance, __newindex = function(t, key, value)
		if pcall(function() return (instance :: any)[key] end) then
			(instance :: any)[key] = value
		else
			rawset(t, key, value)
		end
	end}) :: any
end

function reflectionInstance:getProperties(filter : ReflectionMemberFilter?, validOnly : boolean?): {
		Name: string,
		Serialized: boolean,
		Type: ReflectionType,
		ContentType: Enum.AssetType?,
		Display: {
			Category: string,
			DepreciationMessage: string?,
			LayoutOrder: number,
		}?,
		Permits: {
			Read: SecurityCapabilities?,
			ReadParallel: SecurityCapabilities?,
			Write: SecurityCapabilities?,
			WriteParallel: SecurityCapabilities?,
		},
	}
	local class = self.inst.ClassName
	
	return reflection.getProperties(class, filter, validOnly)
end

function reflectionInstance:getPropertyNames(filter : ReflectionMemberFilter?, validOnly : boolean?) : {string}
	local class = self.inst.ClassName
	
	return reflection.getPropertyNamesFromClass(class, filter, validOnly)
end

return reflection

.new allows for something like this

local part = Instance.new('Part')
part = reflection.new(part)

local partProperties = part:getPropertyNames()
part.Size = Vector3.new(1, 1, 1)

for _, v in partProperties do
    print(part[v])
end
1 Like

Update 1.0.1


πŸ†•Added:
  • GetWritableProperties(ClassName: Instance | string)

  • GetReadableProperties(ClassName: Instance | string)

  • IsPropertyReadable(ClassName: Instance | string, PropertyName: string)

  • IsPropertyWritable(ClassName: Instance | string, PropertyName: string)
    (New name for IsPropertyEditable)

  • IsSignal(ClassName: Instance | string, SignalName: string)
    [:red_exclamation_mark: CURRENTLY NOT IMPLEMENTED :red_exclamation_mark:]

  • IsMethod(ClassName: Instance | string, MethodName: string)
    [:red_exclamation_mark: CURRENTLY NOT IMPLEMENTED :red_exclamation_mark:]

  • IsPropertyEditable / IsPropertyReadable now can return second argument if property not found


:hammer_and_wrench: Fixes:

  • Added support for SecurityCapability:
    ** UI
    ** CapabilityControl
    ** RemoteEvent
    ** Chat

  • Blacklisted SecurityCapability:
    ** RobloxEngine – You can’t access this
    ** RobloxScript – CoreScript
    ** InternalTest – Special beta featues
    ** CSG – If i remember correctly, this is core engine physics related
    ** PluginOrOpenCloud