Move LuaUserData and registration into a proper service

This commit is contained in:
Evil Factory
2026-02-01 00:44:25 -03:00
committed by Maplewheels
parent 9b9529107c
commit 5777b64a18
17 changed files with 908 additions and 1189 deletions

View File

@@ -1,8 +1,8 @@
local defaultLib = {}
local CreateStatic = LuaSetup.LuaUserData.CreateStatic
local CreateEnum = LuaSetup.LuaUserData.CreateEnumTable
local AddCallMetaTable = LuaSetup.LuaUserData.AddCallMetaTable
local CreateStatic = LuaUserData.CreateStatic
local CreateEnum = LuaUserData.CreateEnumTable
local AddCallMetaTable = LuaUserData.AddCallMetaTable
local localizedStrings = {
"LocalizedString", "LimitLString", "WrappedLString", "AddedPunctuationLString", "CapitalizeLString", "ConcatLString", "FallbackLString", "FormattedLString", "InputTypeLString", "JoinLString", "LowerLString", "RawLString", "ReplaceLString", "ServerMsgLString", "SplitLString", "TagLString", "TrimLString", "UpperLString", "StripRichTagsLString",
@@ -79,13 +79,12 @@ defaultLib["GUI"] = {
GUIStyle = CreateStatic("Barotrauma.GUIStyle", true),
}
local guiFallback = defaultLib["GUI"].GUI
setmetatable(defaultLib["GUI"], {
__index = function (table, key)
return defaultLib["GUI"].GUI[key]
__index = function(_, key)
return guiFallback[key]
end
})
AddCallMetaTable(defaultLib["GUI"].VideoPlayer.VideoSettings)
AddCallMetaTable(defaultLib["GUI"].VideoPlayer.TextSettings)
return defaultLib

View File

@@ -1,7 +1,7 @@
local defaultLib = {}
local CreateStatic = LuaSetup.LuaUserData.CreateStatic
local CreateEnum = LuaSetup.LuaUserData.CreateEnumTable
local CreateStatic = LuaUserData.CreateStatic
local CreateEnum = LuaUserData.CreateEnumTable
local localizedStrings = {
"LocalizedString", "AddedPunctuationLString", "CapitalizeLString", "ConcatLString", "FallbackLString", "FormattedLString", "InputTypeLString", "JoinLString", "LowerLString", "RawLString", "ReplaceLString", "ServerMsgLString", "SplitLString", "TagLString", "TrimLString", "UpperLString", "StripRichTagsLString",

View File

@@ -1,8 +1,8 @@
local defaultLib = {}
local AddCallMetaTable = LuaSetup.LuaUserData.AddCallMetaTable
local CreateStatic = LuaSetup.LuaUserData.CreateStatic
local CreateEnum = LuaSetup.LuaUserData.CreateEnumTable
local AddCallMetaTable = LuaUserData.AddCallMetaTable
local CreateStatic = LuaUserData.CreateStatic
local CreateEnum = LuaUserData.CreateEnumTable
defaultLib["SByte"] = CreateStatic("Barotrauma.LuaSByte", true)
defaultLib["Byte"] = CreateStatic("Barotrauma.LuaByte", true)

View File

@@ -1,3 +1,5 @@
if true then return end
local descriptor = LuaUserData.RegisterType("Barotrauma.LuaCsSteam")
LuaUserData.AddMethod(descriptor, "GetWorkshopCollection", function (id, callback)

View File

@@ -1,150 +0,0 @@
local Register = LuaSetup.LuaUserData.RegisterType
local RegisterBarotrauma = LuaSetup.LuaUserData.RegisterTypeBarotrauma
local localizedStrings = {
"LocalizedString", "LimitLString", "WrappedLString", "AddedPunctuationLString", "CapitalizeLString", "ConcatLString", "FallbackLString", "FormattedLString", "InputTypeLString", "JoinLString", "LowerLString", "RawLString", "ReplaceLString", "ServerMsgLString", "SplitLString", "TagLString", "TrimLString", "UpperLString", "StripRichTagsLString",
}
for key, value in pairs(localizedStrings) do
RegisterBarotrauma(value)
end
RegisterBarotrauma("EditorScreen")
RegisterBarotrauma("SubEditorScreen")
RegisterBarotrauma("EventEditorScreen")
RegisterBarotrauma("CharacterEditor.CharacterEditorScreen")
RegisterBarotrauma("SpriteEditorScreen")
RegisterBarotrauma("LevelEditorScreen")
RegisterBarotrauma("Networking.ClientPeer")
RegisterBarotrauma("Networking.GameClient")
RegisterBarotrauma("Networking.VoipCapture")
RegisterBarotrauma("Media.Video")
RegisterBarotrauma("SoundsFile")
RegisterBarotrauma("SoundPrefab")
RegisterBarotrauma("PrefabCollection`1")
RegisterBarotrauma("PrefabSelector`1")
RegisterBarotrauma("BackgroundMusic")
RegisterBarotrauma("GUISound")
RegisterBarotrauma("DamageSound")
RegisterBarotrauma("Sounds.SoundManager")
RegisterBarotrauma("Sounds.OggSound")
RegisterBarotrauma("Sounds.VideoSound")
RegisterBarotrauma("Sounds.VoipSound")
RegisterBarotrauma("Sounds.SoundChannel")
RegisterBarotrauma("Sounds.SoundBuffers")
RegisterBarotrauma("RoundSound")
RegisterBarotrauma("CharacterSound")
RegisterBarotrauma("SoundPlayer")
RegisterBarotrauma("Items.Components.ItemSound")
RegisterBarotrauma("Sounds.LowpassFilter")
RegisterBarotrauma("Sounds.HighpassFilter")
RegisterBarotrauma("Sounds.BandpassFilter")
RegisterBarotrauma("Sounds.NotchFilter")
RegisterBarotrauma("Sounds.LowShelfFilter")
RegisterBarotrauma("Sounds.HighShelfFilter")
RegisterBarotrauma("Sounds.PeakFilter")
RegisterBarotrauma("Particles.ParticleManager")
RegisterBarotrauma("Particles.Particle")
RegisterBarotrauma("Particles.ParticleEmitterProperties")
RegisterBarotrauma("Particles.ParticleEmitter")
RegisterBarotrauma("Particles.ParticlePrefab")
RegisterBarotrauma("Lights.LightManager")
RegisterBarotrauma("Lights.LightSource")
RegisterBarotrauma("Lights.LightSourceParams")
RegisterBarotrauma("LevelWallVertexBuffer")
RegisterBarotrauma("LevelRenderer")
RegisterBarotrauma("WaterRenderer")
RegisterBarotrauma("WaterVertexData")
RegisterBarotrauma("ChatBox")
RegisterBarotrauma("GUICanvas")
RegisterBarotrauma("Anchor")
RegisterBarotrauma("Alignment")
RegisterBarotrauma("Pivot")
RegisterBarotrauma("Key")
RegisterBarotrauma("PlayerInput")
RegisterBarotrauma("ScalableFont")
Register("Microsoft.Xna.Framework.Graphics.Effect")
Register("Microsoft.Xna.Framework.Graphics.EffectParameterCollection")
Register("Microsoft.Xna.Framework.Graphics.EffectParameter")
Register("Microsoft.Xna.Framework.Graphics.SpriteBatch")
Register("Microsoft.Xna.Framework.Graphics.Texture2D")
Register("EventInput.KeyboardDispatcher")
Register("EventInput.KeyEventArgs")
Register("Microsoft.Xna.Framework.Input.Keys")
Register("Microsoft.Xna.Framework.Input.KeyboardState")
RegisterBarotrauma("TextureLoader")
RegisterBarotrauma("Sprite")
RegisterBarotrauma("GUI")
RegisterBarotrauma("GUIStyle")
RegisterBarotrauma("GUIComponent")
RegisterBarotrauma("GUILayoutGroup")
RegisterBarotrauma("GUITextBox")
RegisterBarotrauma("GUITextBlock")
RegisterBarotrauma("GUIButton")
RegisterBarotrauma("RectTransform")
RegisterBarotrauma("GUIFrame")
RegisterBarotrauma("GUITickBox")
RegisterBarotrauma("GUIImage")
RegisterBarotrauma("GUIListBox")
RegisterBarotrauma("GUIScrollBar")
RegisterBarotrauma("GUIDropDown")
RegisterBarotrauma("GUINumberInput")
RegisterBarotrauma("GUIMessage")
RegisterBarotrauma("GUIMessageBox")
RegisterBarotrauma("GUIColorPicker")
RegisterBarotrauma("GUIProgressBar")
RegisterBarotrauma("GUICustomComponent")
RegisterBarotrauma("GUIScissorComponent")
RegisterBarotrauma("GUIComponentStyle")
RegisterBarotrauma("GUIFontPrefab")
RegisterBarotrauma("GUIFont")
RegisterBarotrauma("GUISpritePrefab")
RegisterBarotrauma("GUISprite")
RegisterBarotrauma("GUISpriteSheetPrefab")
RegisterBarotrauma("GUISpriteSheet")
RegisterBarotrauma("GUICursorPrefab")
RegisterBarotrauma("GUICursor")
RegisterBarotrauma("GUIRadioButtonGroup")
RegisterBarotrauma("GUIDragHandle")
RegisterBarotrauma("GUIContextMenu")
RegisterBarotrauma("ContextMenuOption")
RegisterBarotrauma("VideoPlayer")
RegisterBarotrauma("CreditsPlayer")
RegisterBarotrauma("SlideshowPlayer")
RegisterBarotrauma("SerializableEntityEditor")
RegisterBarotrauma("CircuitBoxWireRenderer")
RegisterBarotrauma("CircuitBoxLabel")
RegisterBarotrauma("CircuitBoxMouseDragSnapshotHandler")
RegisterBarotrauma("CircuitBoxUI")
RegisterBarotrauma("SettingsMenu")
RegisterBarotrauma("TabMenu")
RegisterBarotrauma("Widget")
RegisterBarotrauma("UpgradeStore")
RegisterBarotrauma("VotingInterface")
RegisterBarotrauma("MedicalClinicUI")
RegisterBarotrauma("LoadingScreen")
RegisterBarotrauma("HUD")
RegisterBarotrauma("HUDLayoutSettings")
RegisterBarotrauma("HUDProgressBar")
RegisterBarotrauma("Graph")
RegisterBarotrauma("HRManagerUI")
RegisterBarotrauma("SubmarineSelection")
RegisterBarotrauma("Store")
RegisterBarotrauma("UISprite")
RegisterBarotrauma("ParamsEditor")
RegisterBarotrauma("Inventory+SlotReference")
RegisterBarotrauma("VisualSlot")

View File

@@ -1,20 +0,0 @@
local Register = LuaSetup.LuaUserData.RegisterType
local RegisterBarotrauma = LuaSetup.LuaUserData.RegisterTypeBarotrauma
local localizedStrings = {
"LocalizedString", "AddedPunctuationLString", "CapitalizeLString", "ConcatLString", "FallbackLString", "FormattedLString", "InputTypeLString", "JoinLString", "LowerLString", "RawLString", "ReplaceLString", "ServerMsgLString", "SplitLString", "TagLString", "TrimLString", "UpperLString", "StripRichTagsLString",
}
for key, value in pairs(localizedStrings) do
RegisterBarotrauma(value)
end
Register("Steamworks.SteamServer")
RegisterBarotrauma("Character+TeamChangeEventData")
RegisterBarotrauma("Networking.GameServer")
RegisterBarotrauma("Networking.ServerPeer")
RegisterBarotrauma("Networking.FileSender")

View File

@@ -1,479 +0,0 @@
local Register = LuaSetup.LuaUserData.RegisterType
local RegisterExtension = LuaSetup.LuaUserData.RegisterExtensionType
local RegisterBarotrauma = LuaSetup.LuaUserData.RegisterTypeBarotrauma
Register("System.TimeSpan")
Register("System.Exception")
Register("System.Console")
Register("System.Exception")
RegisterBarotrauma("Success`2")
RegisterBarotrauma("Failure`2")
RegisterBarotrauma("LuaSByte")
RegisterBarotrauma("LuaByte")
RegisterBarotrauma("LuaInt16")
RegisterBarotrauma("LuaUInt16")
RegisterBarotrauma("LuaInt32")
RegisterBarotrauma("LuaUInt32")
RegisterBarotrauma("LuaInt64")
RegisterBarotrauma("LuaUInt64")
RegisterBarotrauma("LuaSingle")
RegisterBarotrauma("LuaDouble")
RegisterBarotrauma("GameMain")
RegisterBarotrauma("Networking.BanList")
RegisterBarotrauma("Networking.BannedPlayer")
RegisterBarotrauma("Range`1")
RegisterBarotrauma("RichString")
RegisterBarotrauma("Identifier")
RegisterBarotrauma("LanguageIdentifier")
RegisterBarotrauma("Job")
RegisterBarotrauma("JobPrefab")
RegisterBarotrauma("JobVariant")
Register("Voronoi2.DoubleVector2")
Register("Voronoi2.Site")
Register("Voronoi2.Edge")
Register("Voronoi2.Halfedge")
Register("Voronoi2.VoronoiCell")
Register("Voronoi2.GraphEdge")
RegisterBarotrauma("WayPoint")
RegisterBarotrauma("Level")
RegisterBarotrauma("LevelData")
RegisterBarotrauma("Level+InterestingPosition")
RegisterBarotrauma("LevelGenerationParams")
RegisterBarotrauma("LevelObjectManager")
RegisterBarotrauma("LevelObject")
RegisterBarotrauma("LevelObjectPrefab")
RegisterBarotrauma("LevelTrigger")
RegisterBarotrauma("CaveGenerationParams")
RegisterBarotrauma("CaveGenerator")
RegisterBarotrauma("OutpostGenerationParams")
RegisterBarotrauma("OutpostGenerator")
RegisterBarotrauma("OutpostModuleInfo")
RegisterBarotrauma("BeaconStationInfo")
RegisterBarotrauma("NPCSet")
RegisterBarotrauma("RuinGeneration.Ruin")
RegisterBarotrauma("RuinGeneration.RuinGenerationParams")
RegisterBarotrauma("LevelWall")
RegisterBarotrauma("DestructibleLevelWall")
RegisterBarotrauma("Biome")
RegisterBarotrauma("Map")
RegisterBarotrauma("Networking.RespawnManager")
RegisterBarotrauma("Networking.RespawnManager+TeamSpecificState")
RegisterBarotrauma("Character")
RegisterBarotrauma("CharacterPrefab")
RegisterBarotrauma("CharacterInfo")
RegisterBarotrauma("CharacterInfoPrefab")
RegisterBarotrauma("CharacterInfo+HeadPreset")
RegisterBarotrauma("CharacterInfo+HeadInfo")
RegisterBarotrauma("CharacterHealth")
RegisterBarotrauma("CharacterHealth+LimbHealth")
RegisterBarotrauma("DamageModifier")
RegisterBarotrauma("CharacterInventory")
RegisterBarotrauma("CharacterParams")
RegisterBarotrauma("CharacterParams+AIParams")
RegisterBarotrauma("CharacterParams+TargetParams")
RegisterBarotrauma("CharacterParams+InventoryParams")
RegisterBarotrauma("CharacterParams+HealthParams")
RegisterBarotrauma("CharacterParams+ParticleParams")
RegisterBarotrauma("CharacterParams+SoundParams")
RegisterBarotrauma("SteeringManager")
RegisterBarotrauma("IndoorsSteeringManager")
RegisterBarotrauma("SteeringPath")
RegisterBarotrauma("CreatureMetrics")
RegisterBarotrauma("Item")
RegisterBarotrauma("DeconstructItem")
RegisterBarotrauma("PurchasedItem")
RegisterBarotrauma("PurchasedItemSwap")
RegisterBarotrauma("PurchasedUpgrade")
RegisterBarotrauma("SoldItem")
RegisterBarotrauma("StartItem")
RegisterBarotrauma("StartItemSet")
RegisterBarotrauma("RelatedItem")
RegisterBarotrauma("UpgradeManager")
RegisterBarotrauma("CargoManager")
RegisterBarotrauma("HireManager")
RegisterBarotrauma("FabricationRecipe")
RegisterBarotrauma("PreferredContainer")
RegisterBarotrauma("SwappableItem")
RegisterBarotrauma("FabricationRecipe+RequiredItemByIdentifier")
RegisterBarotrauma("FabricationRecipe+RequiredItemByTag")
RegisterBarotrauma("Submarine")
RegisterBarotrauma("Networking.AccountInfo")
RegisterBarotrauma("Networking.AccountId")
RegisterBarotrauma("Networking.SteamId")
RegisterBarotrauma("Networking.EpicAccountId")
RegisterBarotrauma("Networking.Address")
RegisterBarotrauma("Networking.UnknownAddress")
RegisterBarotrauma("Networking.P2PAddress")
RegisterBarotrauma("Networking.EosP2PAddress")
RegisterBarotrauma("Networking.SteamP2PAddress")
RegisterBarotrauma("Networking.PipeAddress")
RegisterBarotrauma("Networking.LidgrenAddress")
RegisterBarotrauma("Networking.Endpoint")
RegisterBarotrauma("Networking.SteamP2PEndpoint")
RegisterBarotrauma("Networking.PipeEndpoint")
RegisterBarotrauma("Networking.LidgrenEndpoint")
RegisterBarotrauma("INetSerializableStruct")
RegisterBarotrauma("Networking.Client")
RegisterBarotrauma("Networking.TempClient")
RegisterBarotrauma("Networking.NetworkConnection")
RegisterBarotrauma("Networking.LidgrenConnection")
RegisterBarotrauma("Networking.SteamP2PConnection")
RegisterBarotrauma("Networking.VoipQueue")
RegisterBarotrauma("Networking.ChatMessage")
RegisterBarotrauma("AnimController")
RegisterBarotrauma("HumanoidAnimController")
RegisterBarotrauma("FishAnimController")
RegisterBarotrauma("Limb")
RegisterBarotrauma("Ragdoll")
RegisterBarotrauma("RagdollParams")
RegisterBarotrauma("AfflictionPrefab")
RegisterBarotrauma("Affliction")
RegisterBarotrauma("AttackResult")
RegisterBarotrauma("Attack")
RegisterBarotrauma("Entity")
RegisterBarotrauma("EntityGrid")
RegisterBarotrauma("EntitySpawner")
RegisterBarotrauma("MapEntity")
RegisterBarotrauma("MapEntityPrefab")
RegisterBarotrauma("CauseOfDeath")
RegisterBarotrauma("Hull")
RegisterBarotrauma("WallSection")
RegisterBarotrauma("Structure")
RegisterBarotrauma("Gap")
RegisterBarotrauma("PhysicsBody")
RegisterBarotrauma("AbilityFlags")
RegisterBarotrauma("ItemPrefab")
RegisterBarotrauma("ItemAssemblyPrefab")
RegisterBarotrauma("InputType")
RegisterBarotrauma("FireSource")
RegisterBarotrauma("SerializableProperty")
LuaUserData.MakeFieldAccessible(RegisterBarotrauma("StatusEffect"), "user")
RegisterBarotrauma("DurationListElement")
RegisterBarotrauma("PropertyConditional")
RegisterBarotrauma("DelayedListElement")
RegisterBarotrauma("DelayedEffect")
RegisterBarotrauma("ContentPackageManager")
RegisterBarotrauma("ContentPackageManager+PackageSource")
RegisterBarotrauma("ContentPackageManager+EnabledPackages")
RegisterBarotrauma("ContentPackage")
RegisterBarotrauma("RegularPackage")
RegisterBarotrauma("CorePackage")
RegisterBarotrauma("ContentXElement")
RegisterBarotrauma("ContentPath")
RegisterBarotrauma("ContentPackageId")
RegisterBarotrauma("SteamWorkshopId")
RegisterBarotrauma("Md5Hash")
RegisterBarotrauma("AfflictionsFile")
RegisterBarotrauma("BackgroundCreaturePrefabsFile")
RegisterBarotrauma("BallastFloraFile")
RegisterBarotrauma("BeaconStationFile")
RegisterBarotrauma("CaveGenerationParametersFile")
RegisterBarotrauma("CharacterFile")
RegisterBarotrauma("ContentFile")
RegisterBarotrauma("CorpsesFile")
RegisterBarotrauma("DecalsFile")
RegisterBarotrauma("EnemySubmarineFile")
RegisterBarotrauma("EventManagerSettingsFile")
RegisterBarotrauma("FactionsFile")
RegisterBarotrauma("ItemAssemblyFile")
RegisterBarotrauma("ItemFile")
RegisterBarotrauma("JobsFile")
RegisterBarotrauma("LevelGenerationParametersFile")
RegisterBarotrauma("LevelObjectPrefabsFile")
RegisterBarotrauma("LocationTypesFile")
RegisterBarotrauma("MapGenerationParametersFile")
RegisterBarotrauma("MissionsFile")
RegisterBarotrauma("NPCConversationsFile")
RegisterBarotrauma("NPCPersonalityTraitsFile")
RegisterBarotrauma("NPCSetsFile")
RegisterBarotrauma("OrdersFile")
RegisterBarotrauma("OtherFile")
RegisterBarotrauma("OutpostConfigFile")
RegisterBarotrauma("OutpostFile")
RegisterBarotrauma("OutpostModuleFile")
RegisterBarotrauma("ParticlesFile")
RegisterBarotrauma("RandomEventsFile")
RegisterBarotrauma("RuinConfigFile")
RegisterBarotrauma("ServerExecutableFile")
RegisterBarotrauma("SkillSettingsFile")
RegisterBarotrauma("SoundsFile")
RegisterBarotrauma("StartItemsFile")
RegisterBarotrauma("StructureFile")
RegisterBarotrauma("SubmarineFile")
RegisterBarotrauma("TalentsFile")
RegisterBarotrauma("TalentTreesFile")
RegisterBarotrauma("TextFile")
RegisterBarotrauma("TutorialsFile")
RegisterBarotrauma("UIStyleFile")
RegisterBarotrauma("UpgradeModulesFile")
RegisterBarotrauma("WreckAIConfigFile")
RegisterBarotrauma("WreckFile")
Register("System.Xml.Linq.XElement")
Register("System.Xml.Linq.XName")
Register("System.Xml.Linq.XAttribute")
Register("System.Xml.Linq.XContainer")
Register("System.Xml.Linq.XDocument")
Register("System.Xml.Linq.XNode")
RegisterBarotrauma("SubmarineBody")
RegisterBarotrauma("Explosion")
RegisterBarotrauma("Networking.ServerSettings")
RegisterBarotrauma("Networking.ServerSettings+SavedClientPermission")
RegisterBarotrauma("Inventory")
RegisterBarotrauma("ItemInventory")
RegisterBarotrauma("Inventory+ItemSlot")
RegisterBarotrauma("FireSource")
RegisterBarotrauma("AutoItemPlacer")
RegisterBarotrauma("CircuitBoxConnection")
RegisterBarotrauma("CircuitBoxComponent")
RegisterBarotrauma("CircuitBoxNode")
RegisterBarotrauma("CircuitBoxWire")
RegisterBarotrauma("CircuitBoxInputOutputNode")
RegisterBarotrauma("CircuitBoxSelectable")
RegisterBarotrauma("CircuitBoxSizes")
local componentsToRegister = { "DockingPort", "Door", "GeneticMaterial", "Growable", "Holdable", "LevelResource", "ItemComponent", "ItemLabel", "LightComponent", "Controller", "Deconstructor", "Engine", "Fabricator", "OutpostTerminal", "Pump", "Reactor", "Steering", "PowerContainer", "Projectile", "Repairable", "Rope", "Scanner", "ButtonTerminal", "ConnectionPanel", "CustomInterface", "MemoryComponent", "Terminal", "WifiComponent", "Wire", "TriggerComponent", "ElectricalDischarger", "EntitySpawnerComponent", "ProducedItem", "VineTile", "GrowthSideExtension", "IdCard", "MeleeWeapon", "Pickable", "AbilityItemPickingTime", "Propulsion", "RangedWeapon", "AbilityRangedWeapon", "RepairTool", "Sprayer", "Throwable", "ItemContainer", "AbilityItemContainer", "Ladder", "LimbPos", "AbilityDeconstructedItem", "AbilityItemCreationMultiplier", "AbilityItemDeconstructedInventory", "MiniMap", "OxygenGenerator", "Sonar", "SonarTransducer", "Vent", "NameTag", "Planter", "Powered", "PowerTransfer", "Quality", "RemoteController", "AdderComponent", "AndComponent", "ArithmeticComponent", "ColorComponent", "ConcatComponent", "Connection", "CircuitBox", "DelayComponent", "DivideComponent", "EqualsComponent", "ExponentiationComponent", "FunctionComponent", "GreaterComponent", "ModuloComponent", "MotionSensor", "MultiplyComponent", "NotComponent", "OrComponent", "OscillatorComponent", "OxygenDetector", "RegExFindComponent", "RelayComponent", "SignalCheckComponent", "SmokeDetector", "StringComponent", "SubtractComponent", "TrigonometricFunctionComponent", "WaterDetector", "XorComponent", "StatusHUD", "Turret", "Wearable",
"GridInfo", "PowerSourceGroup"
}
for key, value in pairs(componentsToRegister) do
RegisterBarotrauma("Items.Components." .. value)
end
LuaUserData.MakeFieldAccessible(RegisterBarotrauma("Items.Components.CustomInterface"), "customInterfaceElementList")
RegisterBarotrauma("Items.Components.CustomInterface+CustomInterfaceElement")
RegisterBarotrauma("WearableSprite")
RegisterBarotrauma("AIController")
RegisterBarotrauma("EnemyAIController")
RegisterBarotrauma("HumanAIController")
RegisterBarotrauma("AICharacter")
RegisterBarotrauma("AITarget")
RegisterBarotrauma("AITargetMemory")
RegisterBarotrauma("AIChatMessage")
RegisterBarotrauma("AIObjectiveManager")
RegisterBarotrauma("WreckAI")
RegisterBarotrauma("WreckAIConfig")
RegisterBarotrauma("AIObjectiveChargeBatteries")
RegisterBarotrauma("AIObjective")
RegisterBarotrauma("AIObjectiveCleanupItem")
RegisterBarotrauma("AIObjectiveCleanupItems")
RegisterBarotrauma("AIObjectiveCombat")
RegisterBarotrauma("AIObjectiveContainItem")
RegisterBarotrauma("AIObjectiveDeconstructItem")
RegisterBarotrauma("AIObjectiveDeconstructItems")
RegisterBarotrauma("AIObjectiveEscapeHandcuffs")
RegisterBarotrauma("AIObjectiveExtinguishFire")
RegisterBarotrauma("AIObjectiveExtinguishFires")
RegisterBarotrauma("AIObjectiveFightIntruders")
RegisterBarotrauma("AIObjectiveFindDivingGear")
RegisterBarotrauma("AIObjectiveFindSafety")
RegisterBarotrauma("AIObjectiveFixLeak")
RegisterBarotrauma("AIObjectiveFixLeaks")
RegisterBarotrauma("AIObjectiveGetItem")
RegisterBarotrauma("AIObjectiveGoTo")
RegisterBarotrauma("AIObjectiveIdle")
RegisterBarotrauma("AIObjectiveOperateItem")
RegisterBarotrauma("AIObjectivePumpWater")
RegisterBarotrauma("AIObjectiveRepairItem")
RegisterBarotrauma("AIObjectiveRepairItems")
RegisterBarotrauma("AIObjectiveRescue")
RegisterBarotrauma("AIObjectiveRescueAll")
RegisterBarotrauma("AIObjectiveReturn")
RegisterBarotrauma("Order")
RegisterBarotrauma("OrderPrefab")
RegisterBarotrauma("OrderTarget")
RegisterBarotrauma("TalentPrefab")
RegisterBarotrauma("TalentOption")
RegisterBarotrauma("TalentSubTree")
RegisterBarotrauma("TalentTree")
RegisterBarotrauma("CharacterTalent")
RegisterBarotrauma("Upgrade")
RegisterBarotrauma("UpgradeCategory")
RegisterBarotrauma("UpgradePrefab")
RegisterBarotrauma("UpgradeManager")
RegisterBarotrauma("Screen")
RegisterBarotrauma("GameScreen")
RegisterBarotrauma("GameSession")
RegisterBarotrauma("GameSettings")
RegisterBarotrauma("CrewManager")
RegisterBarotrauma("KarmaManager")
RegisterBarotrauma("GameMode")
RegisterBarotrauma("MissionMode")
RegisterBarotrauma("PvPMode")
RegisterBarotrauma("Mission")
RegisterBarotrauma("AbandonedOutpostMission")
RegisterBarotrauma("EliminateTargetsMission")
RegisterBarotrauma("EndMission")
RegisterBarotrauma("BeaconMission")
RegisterBarotrauma("CargoMission")
RegisterBarotrauma("CombatMission")
RegisterBarotrauma("EscortMission")
RegisterBarotrauma("GoToMission")
RegisterBarotrauma("MineralMission")
RegisterBarotrauma("MonsterMission")
RegisterBarotrauma("NestMission")
RegisterBarotrauma("PirateMission")
RegisterBarotrauma("SalvageMission")
RegisterBarotrauma("ScanMission")
RegisterBarotrauma("MissionPrefab")
RegisterBarotrauma("CampaignMode")
RegisterBarotrauma("CoOpMode")
RegisterBarotrauma("MultiPlayerCampaign")
RegisterBarotrauma("Radiation")
RegisterBarotrauma("CampaignMetadata")
RegisterBarotrauma("Wallet")
RegisterBarotrauma("Faction")
RegisterBarotrauma("FactionPrefab")
RegisterBarotrauma("Reputation")
RegisterBarotrauma("Location")
RegisterBarotrauma("LocationConnection")
RegisterBarotrauma("LocationType")
RegisterBarotrauma("LocationTypeChange")
RegisterBarotrauma("DebugConsole")
RegisterBarotrauma("DebugConsole+Command")
RegisterBarotrauma("TextManager")
RegisterBarotrauma("TextPack")
local descriptor = RegisterBarotrauma("NetLobbyScreen")
if SERVER then
LuaUserData.MakeFieldAccessible(descriptor, "subs")
end
RegisterBarotrauma("EventManager")
RegisterBarotrauma("EventManagerSettings")
RegisterBarotrauma("Event")
RegisterBarotrauma("ArtifactEvent")
RegisterBarotrauma("MonsterEvent")
RegisterBarotrauma("ScriptedEvent")
RegisterBarotrauma("MalfunctionEvent")
RegisterBarotrauma("EventSet")
RegisterBarotrauma("EventPrefab")
RegisterBarotrauma("Networking.NetConfig")
RegisterBarotrauma("Networking.IWriteMessage")
RegisterBarotrauma("Networking.IReadMessage")
RegisterBarotrauma("Networking.NetEntityEvent")
RegisterBarotrauma("Networking.INetSerializable")
Register("Lidgren.Network.NetIncomingMessage")
Register("Lidgren.Network.NetConnection")
Register("System.Net.IPEndPoint")
Register("System.Net.IPAddress")
RegisterBarotrauma("Skill")
RegisterBarotrauma("SkillPrefab")
RegisterBarotrauma("SkillSettings")
RegisterBarotrauma("TraitorManager")
RegisterBarotrauma("TraitorEvent")
RegisterBarotrauma("TraitorEventPrefab")
RegisterBarotrauma("TraitorManager+TraitorResults")
Register("FarseerPhysics.Dynamics.Body")
Register("FarseerPhysics.Dynamics.World")
Register("FarseerPhysics.Dynamics.Fixture")
Register("FarseerPhysics.ConvertUnits")
Register("FarseerPhysics.Collision.AABB")
Register("FarseerPhysics.Collision.ContactFeature")
Register("FarseerPhysics.Collision.ManifoldPoint")
Register("FarseerPhysics.Collision.ContactID")
Register("FarseerPhysics.Collision.Manifold")
Register("FarseerPhysics.Collision.RayCastInput")
Register("FarseerPhysics.Collision.ClipVertex")
Register("FarseerPhysics.Collision.RayCastOutput")
Register("FarseerPhysics.Collision.EPAxis")
Register("FarseerPhysics.Collision.ReferenceFace")
Register("FarseerPhysics.Collision.Collision")
RegisterBarotrauma("Physics")
local toolBox = RegisterBarotrauma("ToolBox")
if CLIENT then
LuaUserData.RemoveMember(toolBox, "OpenFileWithShell")
end
RegisterBarotrauma("Camera")
RegisterBarotrauma("Key")
RegisterBarotrauma("PrefabCollection`1")
RegisterBarotrauma("PrefabSelector`1")
RegisterBarotrauma("Pair`2")
RegisterBarotrauma("Items.Components.Signal")
RegisterBarotrauma("SubmarineInfo")
RegisterBarotrauma("MapCreatures.Behavior.BallastFloraBehavior")
RegisterBarotrauma("MapCreatures.Behavior.BallastFloraBranch")
RegisterBarotrauma("PetBehavior")
RegisterBarotrauma("SwarmBehavior")
RegisterBarotrauma("LatchOntoAI")
RegisterBarotrauma("Decal")
RegisterBarotrauma("DecalPrefab")
RegisterBarotrauma("DecalManager")
RegisterBarotrauma("PriceInfo")
RegisterBarotrauma("Voting")
Register("Microsoft.Xna.Framework.Vector2")
Register("Microsoft.Xna.Framework.Vector3")
Register("Microsoft.Xna.Framework.Vector4")
Register("Microsoft.Xna.Framework.Color")
Register("Microsoft.Xna.Framework.Point")
Register("Microsoft.Xna.Framework.Rectangle")
Register("Microsoft.Xna.Framework.Matrix")
local friend = Register("Steamworks.Friend")
LuaUserData.RemoveMember(friend, "InviteToGame")
LuaUserData.RemoveMember(friend, "SendMessage")
local workshopItem = Register("Steamworks.Ugc.Item")
LuaUserData.RemoveMember(workshopItem, "Subscribe")
LuaUserData.RemoveMember(workshopItem, "DownloadAsync")
LuaUserData.RemoveMember(workshopItem, "Unsubscribe")
LuaUserData.RemoveMember(workshopItem, "AddFavorite")
LuaUserData.RemoveMember(workshopItem, "RemoveFavorite")
LuaUserData.RemoveMember(workshopItem, "Vote")
LuaUserData.RemoveMember(workshopItem, "GetUserVote")
LuaUserData.RemoveMember(workshopItem, "Edit")
RegisterExtension("Barotrauma.MathUtils")
RegisterExtension("Barotrauma.XMLExtensions")

View File

@@ -6,17 +6,6 @@ package.path = {path .. "/Lua/?.lua"}
setmodulepaths(package.path)
-- Setup Libraries
LuaSetup.LuaUserData = LuaUserData
require("DefaultRegister/RegisterShared")
if SERVER then
require("DefaultRegister/RegisterServer")
else
require("DefaultRegister/RegisterClient")
end
local function AddTableToGlobal(tbl)
for k, v in pairs(tbl) do
_G[k] = v
@@ -35,11 +24,11 @@ AddTableToGlobal(require("CompatibilityLib"))
require("DefaultHook")
Descriptors = LuaSetup.LuaUserData
require("DefaultLib/Utils/Math")
require("DefaultLib/Utils/String")
require("DefaultLib/Utils/Util")
require("DefaultLib/Utils/SteamApi")
require("PostSetup")
LuaSetup = nil

View File

@@ -1,97 +0,0 @@
local clrLuaUserData = LuaUserData
local luaUserData = {}
luaUserData.Descriptors = {}
LuaSetup.LuaUserData = luaUserData
luaUserData.IsRegistered = clrLuaUserData.IsRegistered
luaUserData.UnregisterType = clrLuaUserData.UnregisterType
luaUserData.RegisterGenericType = clrLuaUserData.RegisterGenericType
luaUserData.RegisterExtensionType = clrLuaUserData.RegisterExtensionType
luaUserData.UnregisterGenericType = clrLuaUserData.UnregisterGenericType
luaUserData.IsTargetType = clrLuaUserData.IsTargetType
luaUserData.TypeOf = clrLuaUserData.TypeOf
luaUserData.GetType = clrLuaUserData.GetType
luaUserData.CreateEnumTable = clrLuaUserData.CreateEnumTable
luaUserData.MakeFieldAccessible = clrLuaUserData.MakeFieldAccessible
luaUserData.MakeMethodAccessible = clrLuaUserData.MakeMethodAccessible
luaUserData.MakePropertyAccessible = clrLuaUserData.MakePropertyAccessible
luaUserData.AddMethod = clrLuaUserData.AddMethod
luaUserData.AddField = clrLuaUserData.AddField
luaUserData.RemoveMember = clrLuaUserData.RemoveMember
luaUserData.CreateUserDataFromDescriptor = clrLuaUserData.CreateUserDataFromDescriptor
luaUserData.CreateUserDataFromType = clrLuaUserData.CreateUserDataFromType
luaUserData.HasMember = clrLuaUserData.HasMember
luaUserData.RegisterType = function(typeName)
local success, result = pcall(clrLuaUserData.RegisterType, typeName)
if not success then
error(result, 2)
end
luaUserData.Descriptors[typeName] = result
return result
end
luaUserData.RegisterTypeBarotrauma = function(typeName)
typeName = "Barotrauma." .. typeName
local success, result = pcall(luaUserData.RegisterType, typeName)
if not success then
error(result, 2)
end
return result
end
luaUserData.AddCallMetaTable = function (userdata)
if userdata == nil then
error("Attempted to add a call metatable to a nil value.", 2)
end
if not LuaUserData.HasMember(userdata, ".ctor") then
error("Attempted to add a call metatable to a userdata that does not have a constructor.", 2)
end
debug.setmetatable(userdata, {
__call = function(obj, ...)
if userdata == nil then
error("userdata was nil.", 2)
end
local success, result = pcall(userdata.__new, ...)
if not success then
error(result, 2)
end
return result
end
})
end
luaUserData.CreateStatic = function(typeName)
if type(typeName) ~= "string" then
error("Expected a string for typeName, got " .. type(typeName) .. ".", 2)
end
local success, result = pcall(clrLuaUserData.CreateStatic, typeName)
if not success then
error(result, 2)
end
if result == nil then
return
end
if LuaUserData.HasMember(result, ".ctor") then
luaUserData.AddCallMetaTable(result)
end
return result
end

View File

@@ -1,13 +0,0 @@
if not CSActive then
LuaUserDataIUUD = LuaUserData.RegisterType("Barotrauma.LuaSafeUserData")
LuaUserData = LuaUserData.CreateStatic("Barotrauma.LuaSafeUserData");
for k, v in pairs(debug) do
if k ~= "getmetatable" and k ~= "setmetatable" and k ~= "traceback" then
debug[k] = nil
end
end
end
Descriptors = LuaUserData.__new()
LuaUserDataIUUD = nil

View File

@@ -189,6 +189,10 @@ namespace Barotrauma
servicesProvider.RegisterServiceType<IAssemblyLoaderService.IFactory, AssemblyLoader.Factory>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceResolver<IPluginManagementService>(factory => factory.GetInstance<IAssemblyManagementService>());
servicesProvider.RegisterServiceType<ILuaScriptManagementService, LuaScriptManagementService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<IDefaultLuaRegistrar, DefaultLuaRegistrar>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<ILuaUserDataService, LuaUserDataService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<ISafeLuaUserDataService, SafeLuaUserDataService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<ILuaScriptLoader, LuaScriptLoader>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<LuaGame, LuaGame>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<ILuaCsTimer, LuaCsTimer>(ServiceLifetime.Singleton);

View File

@@ -17,16 +17,10 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static Barotrauma.GameSettings;
namespace Barotrauma.LuaCs.Services;
@@ -39,20 +33,26 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
private List<ILuaScriptResourceInfo> _resourcesInfo = new List<ILuaScriptResourceInfo>();
private readonly AsyncReaderWriterLock _operationsLock = new ();
private readonly ILuaUserDataService _userDataService;
private readonly ISafeLuaUserDataService _safeUserDataService;
private readonly ILuaScriptLoader _luaScriptLoader;
private readonly ILuaScriptServicesConfig _luaScriptServicesConfig;
private readonly ILoggerService _loggerService;
private readonly LuaGame _luaGame;
private readonly ILuaCsHook _luaCsHook;
private readonly ILuaCsTimer _luaCsTimer;
private readonly IDefaultLuaRegistrar _defaultLuaRegistrar;
//private readonly ILuaCsNetworking _luaCsNetworking;
//private readonly ILuaCsUtility _luaCsUtility;
//private readonly ILuaCsTimer _luaCsTimer;
public LuaScriptManagementService(
ILoggerService loggerService,
ILuaScriptLoader loader,
ILoggerService loggerService,
ILuaScriptLoader loader,
ILuaUserDataService userDataService,
ISafeLuaUserDataService safeUserDataService,
IDefaultLuaRegistrar defaultLuaRegistrar,
ILuaScriptServicesConfig luaScriptServicesConfig,
LuaGame luaGame,
ILuaCsHook luaCsHook,
@@ -62,6 +62,9 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
)
{
_luaScriptLoader = loader;
_userDataService = userDataService;
_safeUserDataService = safeUserDataService;
_defaultLuaRegistrar = defaultLuaRegistrar;
_luaScriptServicesConfig = luaScriptServicesConfig;
_loggerService = loggerService;
@@ -168,16 +171,15 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
Script.GlobalOptions.ShouldPCallCatchException = (Exception ex) => { return true; };
RegisterType(typeof(LuaGame));
RegisterType(typeof(EventService));
RegisterType(typeof(ILuaCsNetworking));
RegisterType(typeof(ILuaCsUtility));
RegisterType(typeof(ILuaCsTimer));
RegisterType(typeof(LuaCsFile));
RegisterType(typeof(ILuaScriptResourceInfo));
RegisterType(typeof(IResourceInfo));
RegisterType(typeof(LuaUserData));
RegisterType(typeof(IUserDataDescriptor));
UserData.RegisterType(typeof(LuaGame));
UserData.RegisterType(typeof(EventService));
UserData.RegisterType(typeof(ILuaCsNetworking));
UserData.RegisterType(typeof(ILuaCsUtility));
UserData.RegisterType(typeof(ILuaCsTimer));
UserData.RegisterType(typeof(LuaCsFile));
UserData.RegisterType(typeof(ILuaScriptResourceInfo));
UserData.RegisterType(typeof(IResourceInfo));
UserData.RegisterType(typeof(IUserDataDescriptor));
new LuaConverters(_script).RegisterLuaConverters();
@@ -193,20 +195,31 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
_script.Globals["dostring"] = (Func<string, Table, string, DynValue>)_script.DoString;
_script.Globals["load"] = (Func<string, Table, string, DynValue>)_script.LoadString;
_script.Globals["Game"] = _luaGame;
_script.Globals["Hook"] = _luaCsHook;
_script.Globals["Timer"] = _luaCsTimer;
_script.Globals["File"] = UserData.CreateStatic<LuaCsFile>();
//_script.Globals["Networking"] = _luaCsNetworking;
//_script.Globals["Steam"] = Steam;
_script.Globals["LuaUserData"] = UserData.CreateStatic<LuaUserData>();
if (GameMain.LuaCs.IsCsEnabled)
{
UserData.RegisterType(typeof(LuaUserDataService));
_script.Globals["LuaUserData"] = _userDataService;
}
else
{
UserData.RegisterType(typeof(SafeLuaUserDataService));
_script.Globals["LuaUserData"] = _safeUserDataService;
}
_script.Globals["ExecutionNumber"] = 0;
_script.Globals["CSActive"] = false;
_script.Globals["SERVER"] = LuaCsSetup.IsServer;
_script.Globals["CLIENT"] = LuaCsSetup.IsClient;
_defaultLuaRegistrar.RegisterAll();
}
public FluentResults.Result ExecuteLoadedScripts(ImmutableArray<ILuaScriptResourceInfo> executionOrder)
@@ -291,24 +304,17 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService
public FluentResults.Result Reset()
{
_userDataService.Reset();
return DisposeAllPackageResources();
}
public void Dispose()
{
_userDataService.Dispose();
_luaScriptLoader.Dispose();
IsDisposed = true;
}
public IUserDataDescriptor RegisterType(Type type)
{
return UserData.RegisterType(type);
}
public void UnregisterType(Type type)
{
UserData.UnregisterType(type, true);
}
public object? GetGlobalTableValue(string tableName)
{
if (!IsRunning) { return null; }

View File

@@ -0,0 +1,177 @@
using Barotrauma.Networking;
using MoonSharp.Interpreter;
using Sigil;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace Barotrauma.LuaCs.Services;
public interface IDefaultLuaRegistrar : IService
{
public void RegisterAll();
}
public class DefaultLuaRegistrar : IDefaultLuaRegistrar
{
public bool IsDisposed { get; private set; }
private readonly ILuaUserDataService _userDataService;
private readonly ISafeLuaUserDataService _safeUserDataService;
private readonly ILoggerService _loggerService;
public DefaultLuaRegistrar(ILoggerService loggerService, ILuaUserDataService userDataService, ISafeLuaUserDataService safeUserDataService)
{
_userDataService = userDataService;
_safeUserDataService = safeUserDataService;
_loggerService = loggerService;
}
private void RegisterShared()
{
_userDataService.RegisterType("System.TimeSpan");
_userDataService.RegisterType("System.Exception");
_userDataService.RegisterType("System.Console");
_userDataService.RegisterType("System.Exception");
_userDataService.RegisterType("Barotrauma.Success`2");
_userDataService.RegisterType("Barotrauma.Failure`2");
_userDataService.RegisterType("Barotrauma.Range`1");
List<Assembly> assembliesToScan = [typeof(DefaultLuaRegistrar).Assembly, typeof(Identifier).Assembly, typeof(Microsoft.Xna.Framework.Vector2).Assembly];
foreach (var type in assembliesToScan.SelectMany(a => a.GetTypes()))
{
if (type.IsEnum || type.IsDefined(typeof(CompilerGeneratedAttribute)) || !_safeUserDataService.IsAllowed(type.FullName))
{
continue;
}
_loggerService.LogMessage($"Registered {type.FullName}");
_userDataService.RegisterType(type.FullName);
}
_userDataService.RegisterType("Barotrauma.LuaSByte");
_userDataService.RegisterType("Barotrauma.LuaByte");
_userDataService.RegisterType("Barotrauma.LuaInt16");
_userDataService.RegisterType("Barotrauma.LuaUInt16");
_userDataService.RegisterType("Barotrauma.LuaInt32");
_userDataService.RegisterType("Barotrauma.LuaUInt32");
_userDataService.RegisterType("Barotrauma.LuaInt64");
_userDataService.RegisterType("Barotrauma.LuaUInt64");
_userDataService.RegisterType("Barotrauma.LuaSingle");
_userDataService.RegisterType("Barotrauma.LuaDouble");
_userDataService.RegisterType("Barotrauma.Level+InterestingPosition");
_userDataService.RegisterType("Barotrauma.Networking.RespawnManager+TeamSpecificState");
_userDataService.RegisterType("Barotrauma.CharacterParams+AIParams");
_userDataService.RegisterType("Barotrauma.CharacterParams+TargetParams");
_userDataService.RegisterType("Barotrauma.CharacterParams+InventoryParams");
_userDataService.RegisterType("Barotrauma.CharacterParams+HealthParams");
_userDataService.RegisterType("Barotrauma.CharacterParams+ParticleParams");
_userDataService.RegisterType("Barotrauma.CharacterParams+SoundParams");
_userDataService.RegisterType("Barotrauma.FabricationRecipe+RequiredItemByIdentifier");
_userDataService.RegisterType("Barotrauma.FabricationRecipe+RequiredItemByTag");
_userDataService.MakeFieldAccessible(_userDataService.RegisterType("Barotrauma.StatusEffect"), "user");
_userDataService.RegisterType("Barotrauma.ContentPackageManager+PackageSource");
_userDataService.RegisterType("Barotrauma.ContentPackageManager+EnabledPackages");
_userDataService.RegisterType("System.Xml.Linq.XElement");
_userDataService.RegisterType("System.Xml.Linq.XName");
_userDataService.RegisterType("System.Xml.Linq.XAttribute");
_userDataService.RegisterType("System.Xml.Linq.XContainer");
_userDataService.RegisterType("System.Xml.Linq.XDocument");
_userDataService.RegisterType("System.Xml.Linq.XNode");
_userDataService.RegisterType("Barotrauma.Networking.ServerSettings+SavedClientPermission");
_userDataService.RegisterType("Barotrauma.Inventory+ItemSlot");
_userDataService.MakeFieldAccessible(_userDataService.RegisterType("Barotrauma.Items.Components.CustomInterface"), "customInterfaceElementList");
_userDataService.RegisterType("Barotrauma.Items.Components.CustomInterface+CustomInterfaceElement");
_userDataService.RegisterType("Barotrauma.DebugConsole+Command");
{
var descriptor = _userDataService.RegisterType("Barotrauma.NetLobbyScreen");
#if SERVER
_userDataService.MakeFieldAccessible(descriptor, "subs");
#endif
}
_userDataService.RegisterType("FarseerPhysics.Dynamics.Body");
_userDataService.RegisterType("FarseerPhysics.Dynamics.World");
_userDataService.RegisterType("FarseerPhysics.Dynamics.Fixture");
_userDataService.RegisterType("FarseerPhysics.ConvertUnits");
_userDataService.RegisterType("FarseerPhysics.Collision.AABB");
_userDataService.RegisterType("FarseerPhysics.Collision.ContactFeature");
_userDataService.RegisterType("FarseerPhysics.Collision.ManifoldPoint");
_userDataService.RegisterType("FarseerPhysics.Collision.ContactID");
_userDataService.RegisterType("FarseerPhysics.Collision.Manifold");
_userDataService.RegisterType("FarseerPhysics.Collision.RayCastInput");
_userDataService.RegisterType("FarseerPhysics.Collision.ClipVertex");
_userDataService.RegisterType("FarseerPhysics.Collision.RayCastOutput");
_userDataService.RegisterType("FarseerPhysics.Collision.EPAxis");
_userDataService.RegisterType("FarseerPhysics.Collision.ReferenceFace");
_userDataService.RegisterType("FarseerPhysics.Collision.Collision");
_userDataService.RegisterType("Barotrauma.PrefabCollection`1");
_userDataService.RegisterType("Barotrauma.PrefabSelector`1");
_userDataService.RegisterType("Barotrauma.Pair`2");
var toolBox = UserData.RegisterType(typeof(ToolBox));
#if CLIENT
_userDataService.RemoveMember(toolBox, "OpenFileWithShell");
#endif
}
#if CLIENT
private void RegisterClient()
{
_userDataService.RegisterType("Microsoft.Xna.Framework.Graphics.Effect");
_userDataService.RegisterType("Microsoft.Xna.Framework.Graphics.EffectParameterCollection");
_userDataService.RegisterType("Microsoft.Xna.Framework.Graphics.EffectParameter");
_userDataService.RegisterType("Microsoft.Xna.Framework.Graphics.SpriteBatch");
_userDataService.RegisterType("Microsoft.Xna.Framework.Graphics.Texture2D");
_userDataService.RegisterType("EventInput.KeyboardDispatcher");
_userDataService.RegisterType("EventInput.KeyEventArgs");
_userDataService.RegisterType("Microsoft.Xna.Framework.Input.Keys");
_userDataService.RegisterType("Microsoft.Xna.Framework.Input.KeyboardState");
_userDataService.RegisterType("Barotrauma.Inventory+SlotReference");
}
#elif SERVER
private void RegisterServer()
{
_userDataService.RegisterType("Barotrauma.Character+TeamChangeEventData");
}
#endif
public void RegisterAll()
{
RegisterShared();
#if CLIENT
RegisterClient();
#elif SERVER
RegisterServer();
#endif
}
public void Dispose()
{
IsDisposed = true;
}
}

View File

@@ -1,367 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
namespace Barotrauma
{
internal class LuaUserData
{
[Obsolete("Use IPluginManagementService::GetTypesByName()")]
public static Type GetType(string typeName) => GameMain.LuaCs.PluginManagementService.GetType(typeName, includeInterfaces: true); //LuaCsSetup.GetType(typeName);
public static IUserDataDescriptor RegisterType(string typeName)
{
Type type = GetType(typeName);
if (type == null)
{
throw new ScriptRuntimeException($"tried to register a type that doesn't exist: {typeName}.");
}
return UserData.RegisterType(type);
}
public static void RegisterExtensionType(string typeName)
{
Type type = GetType(typeName);
if (type == null)
{
throw new ScriptRuntimeException($"tried to register a type that doesn't exist: {typeName}.");
}
UserData.RegisterExtensionType(type);
}
public static bool IsRegistered(string typeName)
{
Type type = GetType(typeName);
if (type == null)
{
return false;
}
return UserData.GetDescriptorForType(type, true) != null;
}
public static void UnregisterType(string typeName, bool deleteHistory = false)
{
Type type = GetType(typeName);
if (type == null)
{
throw new ScriptRuntimeException($"tried to unregister a type that doesn't exist: {typeName}.");
}
UserData.UnregisterType(type, deleteHistory);
}
public static IUserDataDescriptor RegisterGenericType(string typeName, params string[] typeNameArguements)
{
Type type = GetType(typeName);
Type[] typeArguements = typeNameArguements.Select(x => GetType(x)).ToArray();
Type genericType = type.MakeGenericType(typeArguements);
return UserData.RegisterType(genericType);
}
public static void UnregisterGenericType(string typeName, params string[] typeNameArguements)
{
Type type = GetType(typeName);
Type[] typeArguements = typeNameArguements.Select(x => GetType(x)).ToArray();
Type genericType = type.MakeGenericType(typeArguements);
UserData.UnregisterType(genericType);
}
public static bool IsTargetType(object obj, string typeName)
{
if (obj == null) { throw new ScriptRuntimeException("userdata is nil"); }
Type targetType = GetType(typeName);
if (targetType == null) { throw new ScriptRuntimeException("target type not found"); }
Type type = obj is Type ? (Type)obj : obj.GetType();
return targetType.IsAssignableFrom(type);
}
public static string TypeOf(object obj)
{
if (obj == null) { throw new ScriptRuntimeException("userdata is nil"); }
return obj.GetType().FullName;
}
public static object CreateStatic(string typeName)
{
Type type = GetType(typeName);
if (type == null)
{
throw new ScriptRuntimeException($"tried to create a static userdata of a type that doesn't exist: {typeName}.");
}
MethodInfo method = typeof(UserData).GetMethod(nameof(UserData.CreateStatic), 1, new Type[0]);
MethodInfo generic = method.MakeGenericMethod(type);
return generic.Invoke(null, null);
}
public static object CreateEnumTable(string typeName)
{
Type type = GetType(typeName);
if (type == null)
{
throw new ScriptRuntimeException($"tried to create an enum table with a type that doesn't exist:: {typeName}.");
}
Dictionary<string, object> result = new Dictionary<string, object>();
foreach (var value in Enum.GetValues(type))
{
string name = Enum.GetName(type, value);
result[name] = value;
}
return result;
}
private static FieldInfo FindFieldRecursively(Type type, string fieldName)
{
var field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
if (field == null && type.BaseType != null)
{
return FindFieldRecursively(type.BaseType, fieldName);
}
return field;
}
public static void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {fieldName} accessible.");
}
var descriptor = (StandardUserDataDescriptor)IUUD;
FieldInfo field = FindFieldRecursively(IUUD.Type, fieldName);
if (field == null)
{
throw new ScriptRuntimeException($"tried to make field '{fieldName}' accessible, but the field doesn't exist.");
}
descriptor.RemoveMember(fieldName);
descriptor.AddMember(fieldName, new FieldMemberDescriptor(field, InteropAccessMode.Default));
}
private static MethodInfo FindMethodRecursively(Type type, string methodName, Type[] types = null)
{
MethodInfo method;
if (types == null)
{
method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
}
else
{
method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, types);
}
if (method == null && type.BaseType != null)
{
return FindMethodRecursively(type.BaseType, methodName, types);
}
return method;
}
public static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName, string[] parameters = null)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {methodName} accessible.");
}
Type[] parameterTypes = null;
if (parameters != null)
{
parameterTypes = new Type[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
Type type = LuaUserData.GetType(parameters[i]);
if (type == null)
{
throw new ScriptRuntimeException($"invalid parameter type '{parameters[i]}'");
}
parameterTypes[i] = type;
}
}
var descriptor = (StandardUserDataDescriptor)IUUD;
MethodBase method;
try
{
method = FindMethodRecursively(IUUD.Type, methodName, parameterTypes);
}
catch (AmbiguousMatchException ex)
{
throw new ScriptRuntimeException("ambiguous method signature.");
}
if (method == null)
{
throw new ScriptRuntimeException($"tried to make method '{methodName}' accessible, but the method doesn't exist.");
}
descriptor.AddMember(methodName, new MethodMemberDescriptor(method, InteropAccessMode.Default));
}
private static PropertyInfo FindPropertyRecursively(Type type, string propertyName)
{
var property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
if (property == null && type.BaseType != null)
{
return FindPropertyRecursively(type.BaseType, propertyName);
}
return property;
}
public static void MakePropertyAccessible(IUserDataDescriptor IUUD, string propertyName)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {propertyName} accessible.");
}
var descriptor = (StandardUserDataDescriptor)IUUD;
PropertyInfo property = FindPropertyRecursively(IUUD.Type, propertyName);
if (property == null)
{
throw new ScriptRuntimeException($"tried to make property '{propertyName}' accessible, but the property doesn't exist.");
}
descriptor.RemoveMember(propertyName);
descriptor.AddMember(propertyName, new PropertyMemberDescriptor(property, InteropAccessMode.Default, property.GetGetMethod(true), property.GetSetMethod(true)));
}
public static void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to add method {methodName}.");
}
var descriptor = (StandardUserDataDescriptor)IUUD;
descriptor.RemoveMember(methodName);
descriptor.AddMember(methodName, new ObjectCallbackMemberDescriptor(methodName, (object arg1, ScriptExecutionContext arg2, CallbackArguments arg3) =>
{
/*if (GameMain.LuaCs != null)
return GameMain.LuaCs.CallLuaFunction(function, arg3.GetArray());
return null;*/
throw new NotImplementedException();
}));
}
public static void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to add field {fieldName}.");
}
var descriptor = (StandardUserDataDescriptor)IUUD;
descriptor.RemoveMember(fieldName);
descriptor.AddMember(fieldName, new DynValueMemberDescriptor(fieldName, value));
}
public static void RemoveMember(IUserDataDescriptor IUUD, string memberName)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to remove the member {memberName}.");
}
var descriptor = (StandardUserDataDescriptor)IUUD;
descriptor.RemoveMember(memberName);
}
public static bool HasMember(object obj, string memberName)
{
if (obj == null) { throw new ScriptRuntimeException("object is nil"); }
Type type;
if (obj is Type)
{
type = (Type)obj;
}
else if(obj is IUserDataDescriptor descriptor)
{
type = descriptor.Type;
if (((StandardUserDataDescriptor)descriptor).HasMember(memberName))
{
return true;
}
}
else
{
type = obj.GetType();
}
if (type.GetMember(memberName).Length == 0)
{
return false;
}
return true;
}
/// <summary>
/// See <see cref="CreateUserDataFromType"/>.
/// </summary>
/// <param name="scriptObject">Lua value to convert and wrap in a userdata.</param>
/// <param name="desiredTypeDescriptor">Descriptor of the type of the object to convert the Lua value to. Uses MoonSharp ScriptToClr converters.</param>
/// <returns>A userdata that wraps the Lua value converted to an object of the desired type as described by <paramref name="desiredTypeDescriptor"/>.</returns>
public static DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
{
return UserData.Create(scriptObject.ToObject(desiredTypeDescriptor.Type), desiredTypeDescriptor);
}
/// <summary>
/// Converts a Lua value to a CLR object of a desired type and wraps it in a userdata.
/// If the type is not registered, then a new <see cref="MoonSharp.Interpreter.Interop.StandardUserDataDescriptor"/> will be created and used.
/// The goal of this method is to allow Lua scripts to create userdata to wrap certain data without having to register types.
/// <remarks>Wrapping the value in a userdata preserves the original type during script-to-CLR conversions.</remarks>
/// <example>A Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets
/// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything.
/// Registering the List`1 type can break other scripts relying on default converters, so instead
/// it is better to manually wrap the List`1 object into a userdata.
/// </example>
/// </summary>
/// <param name="scriptObject">Lua value to convert and wrap in a userdata.</param>
/// <param name="desiredType">Type describing the CLR type of the object to convert the Lua value to.</param>
/// <returns>A userdata that wraps the Lua value converted to an object of the desired type.</returns>
public static DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
{
IUserDataDescriptor descriptor = UserData.GetDescriptorForType(desiredType, true);
descriptor ??= new StandardUserDataDescriptor(desiredType, InteropAccessMode.Default);
return CreateUserDataFromDescriptor(scriptObject, descriptor);
}
}
}

View File

@@ -0,0 +1,440 @@
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Barotrauma.LuaCs.Services;
public interface ILuaUserDataService : IReusableService
{
IReadOnlyDictionary<string, IUserDataDescriptor> Descriptors { get; }
IUserDataDescriptor RegisterType(string typeName);
void RegisterExtensionType(string typeName);
bool IsRegistered(string typeName);
void UnregisterType(string typeName, bool deleteHistory = false);
object CreateStatic(string typeName);
bool IsTargetType(object obj, string typeName);
string TypeOf(object obj);
object CreateEnumTable(string typeName);
void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName);
void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName, string[] parameters = null);
void MakePropertyAccessible(IUserDataDescriptor IUUD, string propertyName);
void AddMethod(IUserDataDescriptor IUUD, string methodName, object function);
void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value);
void RemoveMember(IUserDataDescriptor IUUD, string memberName);
bool HasMember(object obj, string memberName);
/// <summary>
/// See <see cref="CreateUserDataFromType"/>.
/// </summary>
/// <param name="scriptObject">Lua value to convert and wrap in a userdata.</param>
/// <param name="desiredTypeDescriptor">Descriptor of the type of the object to convert the Lua value to. Uses MoonSharp ScriptToClr converters.</param>
/// <returns>A userdata that wraps the Lua value converted to an object of the desired type as described by <paramref name="desiredTypeDescriptor"/>.</returns>
DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor);
/// <summary>
/// Converts a Lua value to a CLR object of a desired type and wraps it in a userdata.
/// If the type is not registered, then a new <see cref="MoonSharp.Interpreter.Interop.StandardUserDataDescriptor"/> will be created and used.
/// The goal of this method is to allow Lua scripts to create userdata to wrap certain data without having to register types.
/// <remarks>Wrapping the value in a userdata preserves the original type during script-to-CLR conversions.</remarks>
/// <example>A Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets
/// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything.
/// Registering the List`1 type can break other scripts relying on default converters, so instead
/// it is better to manually wrap the List`1 object into a userdata.
/// </example>
/// </summary>
/// <param name="scriptObject">Lua value to convert and wrap in a userdata.</param>
/// <param name="desiredType">Type describing the CLR type of the object to convert the Lua value to.</param>
/// <returns>A userdata that wraps the Lua value converted to an object of the desired type.</returns>
DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType);
void AddCallMetaTable(object userdata);
}
public class LuaUserDataService : ILuaUserDataService
{
public bool IsDisposed { get; private set; }
public IReadOnlyDictionary<string, IUserDataDescriptor> Descriptors => descriptors;
private ConcurrentDictionary<string, IUserDataDescriptor> descriptors;
private readonly IPluginManagementService _pluginManagementService;
public LuaUserDataService(IPluginManagementService pluginManagementService)
{
descriptors = new ConcurrentDictionary<string, IUserDataDescriptor>();
_pluginManagementService = pluginManagementService;
}
public IUserDataDescriptor this[string key]
{
get
{
return descriptors.GetValueOrDefault(key);
}
}
private Type GetType(string typeName) => _pluginManagementService.GetType(typeName, includeInterfaces: true);
public IUserDataDescriptor RegisterType(string typeName)
{
Type type = GetType(typeName);
if (type == null)
{
throw new ScriptRuntimeException($"tried to register a type that doesn't exist: {typeName}.");
}
return UserData.RegisterType(type, new CallableUserDataDescriptor(type));
}
public void RegisterExtensionType(string typeName)
{
Type type = GetType(typeName);
if (type == null)
{
throw new ScriptRuntimeException($"tried to register a type that doesn't exist: {typeName}.");
}
UserData.RegisterExtensionType(type);
}
public bool IsRegistered(string typeName)
{
Type type = GetType(typeName);
if (type == null)
{
return false;
}
return UserData.GetDescriptorForType(type, true) != null;
}
public void UnregisterType(string typeName, bool deleteHistory = false)
{
Type type = GetType(typeName);
if (type == null)
{
throw new ScriptRuntimeException($"tried to unregister a type that doesn't exist: {typeName}.");
}
UserData.UnregisterType(type, deleteHistory);
}
public bool IsTargetType(object obj, string typeName)
{
if (obj == null) { throw new ScriptRuntimeException("userdata is nil"); }
Type targetType = GetType(typeName);
if (targetType == null) { throw new ScriptRuntimeException("target type not found"); }
Type type = obj is Type ? (Type)obj : obj.GetType();
return targetType.IsAssignableFrom(type);
}
public string TypeOf(object obj)
{
if (obj == null) { throw new ScriptRuntimeException("userdata is nil"); }
return obj.GetType().FullName;
}
public object CreateEnumTable(string typeName)
{
Type type = GetType(typeName);
if (type == null)
{
throw new ScriptRuntimeException($"tried to create an enum table with a type that doesn't exist:: {typeName}.");
}
Dictionary<string, object> result = new Dictionary<string, object>();
foreach (var value in Enum.GetValues(type))
{
string name = Enum.GetName(type, value);
result[name] = value;
}
return result;
}
public object CreateStatic(string typeName)
{
Type type = GetType(typeName);
if (type == null)
{
throw new ScriptRuntimeException($"tried to create a static userdata of a type that doesn't exist: {typeName}.");
}
MethodInfo method = typeof(UserData).GetMethod(nameof(UserData.CreateStatic), 1, new Type[0]);
MethodInfo generic = method.MakeGenericMethod(type);
return generic.Invoke(null, null);
}
private FieldInfo FindFieldRecursively(Type type, string fieldName)
{
var field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
if (field == null && type.BaseType != null)
{
return FindFieldRecursively(type.BaseType, fieldName);
}
return field;
}
public void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {fieldName} accessible.");
}
var descriptor = (StandardUserDataDescriptor)IUUD;
FieldInfo field = FindFieldRecursively(IUUD.Type, fieldName);
if (field == null)
{
throw new ScriptRuntimeException($"tried to make field '{fieldName}' accessible, but the field doesn't exist.");
}
descriptor.RemoveMember(fieldName);
descriptor.AddMember(fieldName, new FieldMemberDescriptor(field, InteropAccessMode.Default));
}
private MethodInfo FindMethodRecursively(Type type, string methodName, Type[] types = null)
{
MethodInfo method;
if (types == null)
{
method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
}
else
{
method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, types);
}
if (method == null && type.BaseType != null)
{
return FindMethodRecursively(type.BaseType, methodName, types);
}
return method;
}
public void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName, string[] parameters = null)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {methodName} accessible.");
}
Type[] parameterTypes = null;
if (parameters != null)
{
parameterTypes = new Type[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
Type type = GetType(parameters[i]);
if (type == null)
{
throw new ScriptRuntimeException($"invalid parameter type '{parameters[i]}'");
}
parameterTypes[i] = type;
}
}
var descriptor = (StandardUserDataDescriptor)IUUD;
MethodBase method;
try
{
method = FindMethodRecursively(IUUD.Type, methodName, parameterTypes);
}
catch (AmbiguousMatchException ex)
{
throw new ScriptRuntimeException("ambiguous method signature.");
}
if (method == null)
{
throw new ScriptRuntimeException($"tried to make method '{methodName}' accessible, but the method doesn't exist.");
}
descriptor.AddMember(methodName, new MethodMemberDescriptor(method, InteropAccessMode.Default));
}
private PropertyInfo FindPropertyRecursively(Type type, string propertyName)
{
var property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
if (property == null && type.BaseType != null)
{
return FindPropertyRecursively(type.BaseType, propertyName);
}
return property;
}
public void MakePropertyAccessible(IUserDataDescriptor IUUD, string propertyName)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {propertyName} accessible.");
}
var descriptor = (StandardUserDataDescriptor)IUUD;
PropertyInfo property = FindPropertyRecursively(IUUD.Type, propertyName);
if (property == null)
{
throw new ScriptRuntimeException($"tried to make property '{propertyName}' accessible, but the property doesn't exist.");
}
descriptor.RemoveMember(propertyName);
descriptor.AddMember(propertyName, new PropertyMemberDescriptor(property, InteropAccessMode.Default, property.GetGetMethod(true), property.GetSetMethod(true)));
}
public void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to add method {methodName}.");
}
var descriptor = (StandardUserDataDescriptor)IUUD;
descriptor.RemoveMember(methodName);
descriptor.AddMember(methodName, new ObjectCallbackMemberDescriptor(methodName, (object arg1, ScriptExecutionContext arg2, CallbackArguments arg3) =>
{
/*if (GameMain.LuaCs != null)
return GameMain.LuaCs.CallLuaFunction(function, arg3.GetArray());
return null;*/
throw new NotImplementedException();
}));
}
public void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to add field {fieldName}.");
}
var descriptor = (StandardUserDataDescriptor)IUUD;
descriptor.RemoveMember(fieldName);
descriptor.AddMember(fieldName, new DynValueMemberDescriptor(fieldName, value));
}
public void RemoveMember(IUserDataDescriptor IUUD, string memberName)
{
if (IUUD == null)
{
throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to remove the member {memberName}.");
}
var descriptor = (StandardUserDataDescriptor)IUUD;
descriptor.RemoveMember(memberName);
}
public bool HasMember(object obj, string memberName)
{
if (obj == null) { throw new ScriptRuntimeException("object is nil"); }
Type type;
if (obj is Type)
{
type = (Type)obj;
}
else if (obj is IUserDataDescriptor descriptor)
{
type = descriptor.Type;
if (((StandardUserDataDescriptor)descriptor).HasMember(memberName))
{
return true;
}
}
else
{
type = obj.GetType();
}
if (type.GetMember(memberName).Length == 0)
{
return false;
}
return true;
}
public DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
{
return UserData.Create(scriptObject.ToObject(desiredTypeDescriptor.Type), desiredTypeDescriptor);
}
public DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
{
IUserDataDescriptor descriptor = UserData.GetDescriptorForType(desiredType, true);
descriptor ??= new StandardUserDataDescriptor(desiredType, InteropAccessMode.Default);
return CreateUserDataFromDescriptor(scriptObject, descriptor);
}
public void AddCallMetaTable(object userdata) { }
public void Dispose()
{
IsDisposed = true;
descriptors.Clear();
}
public FluentResults.Result Reset()
{
descriptors.Clear();
return FluentResults.Result.Ok();
}
}
sealed class CallableUserDataDescriptor : StandardUserDataDescriptor
{
public CallableUserDataDescriptor(Type type)
: base(type, InteropAccessMode.Default)
{
}
public override DynValue MetaIndex(Script script, object obj, string metaname)
{
if (metaname == "__call")
{
return DynValue.NewCallback((ctx, args) =>
{
var self = args[0];
var ctor = base.Index(script, obj, DynValue.NewString("__new"), true);
if (ctor == null || ctor.IsNil())
{
throw new ScriptRuntimeException("Attempted to call userdata without __new.");
}
var callArgs = args.GetArray().Skip(1).ToArray();
return script.Call(ctor, callArgs);
});
}
return base.MetaIndex(script, obj, metaname);
}
}

View File

@@ -0,0 +1,234 @@
using Barotrauma;
using Barotrauma.LuaCs.Services;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Barotrauma.LuaCs.Services;
public interface ISafeLuaUserDataService : IService
{
bool IsAllowed(string typeName);
IUserDataDescriptor RegisterType(string typeName);
void RegisterExtensionType(string typeName);
bool IsRegistered(string typeName);
void UnregisterType(string typeName, bool deleteHistory = false);
object CreateStatic(string typeName);
bool IsTargetType(object obj, string typeName);
string TypeOf(object obj);
object CreateEnumTable(string typeName);
void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName);
void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName, string[] parameters = null);
void MakePropertyAccessible(IUserDataDescriptor IUUD, string propertyName);
void AddMethod(IUserDataDescriptor IUUD, string methodName, object function);
void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value);
void RemoveMember(IUserDataDescriptor IUUD, string memberName);
bool HasMember(object obj, string memberName);
/// <summary>
/// See <see cref="CreateUserDataFromType"/>.
/// </summary>
/// <param name="scriptObject">Lua value to convert and wrap in a userdata.</param>
/// <param name="desiredTypeDescriptor">Descriptor of the type of the object to convert the Lua value to. Uses MoonSharp ScriptToClr converters.</param>
/// <returns>A userdata that wraps the Lua value converted to an object of the desired type as described by <paramref name="desiredTypeDescriptor"/>.</returns>
DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor);
/// <summary>
/// Converts a Lua value to a CLR object of a desired type and wraps it in a userdata.
/// If the type is not registered, then a new <see cref="MoonSharp.Interpreter.Interop.StandardUserDataDescriptor"/> will be created and used.
/// The goal of this method is to allow Lua scripts to create userdata to wrap certain data without having to register types.
/// <remarks>Wrapping the value in a userdata preserves the original type during script-to-CLR conversions.</remarks>
/// <example>A Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets
/// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything.
/// Registering the List`1 type can break other scripts relying on default converters, so instead
/// it is better to manually wrap the List`1 object into a userdata.
/// </example>
/// </summary>
/// <param name="scriptObject">Lua value to convert and wrap in a userdata.</param>
/// <param name="desiredType">Type describing the CLR type of the object to convert the Lua value to.</param>
/// <returns>A userdata that wraps the Lua value converted to an object of the desired type.</returns>
DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType);
void AddCallMetaTable(object userdata);
}
public class SafeLuaUserDataService : ISafeLuaUserDataService
{
private readonly ILuaUserDataService _userDataService;
public bool IsDisposed { get; private set; }
public SafeLuaUserDataService(ILuaUserDataService userDataService)
{
_userDataService = userDataService;
}
public IUserDataDescriptor this[string key]
{
get
{
return _userDataService.Descriptors.GetValueOrDefault(key);
}
}
private bool CanBeRegistered(string typeName)
{
if (typeName.StartsWith("Barotrauma.Lua", StringComparison.Ordinal) ||
typeName.StartsWith("Barotrauma.Cs", StringComparison.Ordinal) ||
typeName.StartsWith("Barotrauma.LuaCs", StringComparison.Ordinal))
{
return false;
}
if (typeName == "System.Single") { return true; }
if (typeName.StartsWith("System.Collections", StringComparison.Ordinal))
return true;
if (typeName.StartsWith("Microsoft.Xna", StringComparison.Ordinal))
return true;
if (typeName.StartsWith("Barotrauma.IO", StringComparison.Ordinal))
return false;
if (typeName.StartsWith("Barotrauma.ToolBox", StringComparison.Ordinal))
return false;
if (typeName.StartsWith("Barotrauma.SaveUtil", StringComparison.Ordinal))
return false;
if (typeName.StartsWith("Barotrauma.", StringComparison.Ordinal))
return true;
return false;
}
private bool CanBeReRegistered(string typeName)
{
if (typeName.StartsWith("Barotrauma.Lua", StringComparison.Ordinal) ||
typeName.StartsWith("Barotrauma.Cs", StringComparison.Ordinal) ||
typeName.StartsWith("Barotrauma.LuaCs", StringComparison.Ordinal))
{
return false;
}
return true;
}
public bool IsAllowed(string typeName)
{
if (!CanBeReRegistered(typeName) && IsRegistered(typeName))
{
return false;
}
if (!CanBeRegistered(typeName))
{
return false;
}
return true;
}
private void CheckAllowed(string typeName)
{
if (!IsAllowed(typeName))
{
throw new ScriptRuntimeException($"Type {typeName} can't be registered");
}
}
public IUserDataDescriptor RegisterType(string typeName)
{
CheckAllowed(typeName);
return _userDataService.RegisterType(typeName);
}
public void RegisterExtensionType(string typeName)
{
CheckAllowed(typeName);
_userDataService.RegisterExtensionType(typeName);
}
public bool IsRegistered(string typeName)
{
return _userDataService.IsRegistered(typeName);
}
public void UnregisterType(string typeName, bool deleteHistory = false)
{
IsAllowed(typeName);
_userDataService.UnregisterType(typeName, deleteHistory);
}
public object CreateStatic(string typeName)
{
return _userDataService.CreateStatic(typeName);
}
public bool IsTargetType(object obj, string typeName)
{
return _userDataService.IsTargetType(obj, typeName);
}
public string TypeOf(object obj)
{
return _userDataService.TypeOf(obj);
}
public object CreateEnumTable(string typeName)
{
return _userDataService.CreateEnumTable(typeName);
}
public void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
{
_userDataService.MakeFieldAccessible(IUUD, fieldName);
}
public void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName, string[] parameters = null)
{
_userDataService.MakeMethodAccessible(IUUD, methodName, parameters);
}
public void MakePropertyAccessible(IUserDataDescriptor IUUD, string propertyName)
{
_userDataService.MakePropertyAccessible(IUUD, propertyName);
}
public void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
{
_userDataService.AddMethod(IUUD, methodName, function);
}
public void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value)
{
_userDataService.AddField(IUUD, fieldName, value);
}
public void RemoveMember(IUserDataDescriptor IUUD, string memberName)
{
_userDataService.RemoveMember(IUUD, memberName);
}
public bool HasMember(object obj, string memberName)
{
return _userDataService.HasMember(obj, memberName);
}
public DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
{
return _userDataService.CreateUserDataFromDescriptor(scriptObject, desiredTypeDescriptor);
}
public DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
{
return _userDataService.CreateUserDataFromType(scriptObject, desiredType);
}
public void AddCallMetaTable(object userdata) { }
public void Dispose()
{
IsDisposed = true;
}
}

View File

@@ -58,10 +58,4 @@ public interface ILuaScriptManagementService : IReusableService
#endregion
#region Type_Registration
IUserDataDescriptor RegisterType(Type type);
void UnregisterType(Type type);
#endregion
}