using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using Billboards.Modules;
using Billboards.NetcodePatcher;
using FacilityMeltdown.MeltdownSequence.Behaviours;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyCompany("UnloadedHangar")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Adds billboards to several moons")]
[assembly: AssemblyFileVersion("1.3.6.0")]
[assembly: AssemblyInformationalVersion("1.0.7+75e95b7d38c16d78266d6b3452ddfb59cc4fbbc1")]
[assembly: AssemblyProduct("Billboards")]
[assembly: AssemblyTitle("Billboards")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
static <Module>()
{
}
}
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
[HarmonyPatch]
public class MeltdownHandler : MonoBehaviour
{
internal static bool HasMeltdownStarted;
[HarmonyPostfix]
[HarmonyPatch(typeof(MeltdownHandler), "StartMeltdownClientRpc")]
private static void OnMeltdownStarted()
{
if (NetworkManager.Singleton.IsHost && !StartOfRound.Instance.shipIsLeaving)
{
HasMeltdownStarted = true;
NetworkHandler.SwitchMeltdownBillboardServerMessage.SendAllClients(1, true);
}
}
}
namespace Billboards
{
internal class Content
{
public static GameObject[] AssetsList;
public static void Load()
{
LoadAssetsFromAssetBundle();
}
private static void LoadAssetsFromAssetBundle()
{
try
{
string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location);
string text = Path.Combine(directoryName, "bilboards");
AssetBundle val = AssetBundle.LoadFromFile(text);
AssetsList = val.LoadAllAssets<GameObject>();
Plugin.logger.LogInfo((object)"Successfully loaded assets from AssetBundle!");
}
catch (Exception arg)
{
Plugin.logger.LogError((object)$"Error: failed to load assets from AssetBundle.\n\n{arg}");
}
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("Billboards-UnloadedHangar", "Billboards", "1.4.1")]
public class Plugin : BaseUnityPlugin
{
public static class PluginInfo
{
public const string Guid = "Billboards-UnloadedHangar";
public const string Name = "Billboards";
public const string Ver = "1.4.1";
}
internal static Plugin Instance;
internal static ManualLogSource logger;
internal Harmony _harmony;
private void Awake()
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Expected O, but got Unknown
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
logger = Logger.CreateLogSource("Billboards");
logger.LogInfo((object)"Billboards has awoken!");
Content.Load();
NetcodePatcherAwake();
CompatibilityHandler.OnGameLoad();
_harmony = new Harmony("Billboards-UnloadedHangar");
_harmony.PatchAll(typeof(CompatibilityHandler));
_harmony.PatchAll(typeof(NetworkHandler));
_harmony.PatchAll(typeof(ManagerPatchClasses));
}
private void NetcodePatcherAwake()
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
Type[] array = types;
Type[] array2 = array;
foreach (Type type in array2)
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo[] array3 = methods;
MethodInfo[] array4 = array3;
foreach (MethodInfo methodInfo in array4)
{
object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
if (customAttributes.Length != 0)
{
methodInfo.Invoke(null, null);
}
}
}
}
internal static void PatchMeltdownHandler()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
Harmony val = new Harmony("SidePatch");
val.PatchAll(typeof(MeltdownHandler));
}
}
}
namespace Billboards.Modules
{
internal class CompatibilityHandler
{
internal static bool facilityMeltdownPresent;
internal static void OnGameLoad()
{
facilityMeltdownPresent = IsModPresent("me.loaforc.facilitymeltdown", "FacilityMeltdown dettected, executing integration patches...");
if (facilityMeltdownPresent)
{
try
{
Plugin.PatchMeltdownHandler();
Plugin.logger.LogInfo((object)"PatchingMeltdownHandler");
}
catch (Exception ex)
{
Plugin.logger.LogError((object)ex);
}
}
}
private static bool IsModPresent(string name, string logMessage)
{
bool flag = Chainloader.PluginInfos.ContainsKey(name);
if (flag)
{
Plugin.logger.LogInfo((object)(name + " is present. " + logMessage));
}
return flag;
}
}
internal class FrameworkLibrary : MonoBehaviour
{
public static FrameworkLibrary Instance { get; private set; }
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
Plugin.logger.LogWarning((object)"Attemping to instantiate class");
}
}
[Obsolete("Incompatible", true)]
public static void PlanetExtractor()
{
if (((object)RoundManager.Instance.currentLevel).ToString() == "ArtificeLevel (SelectableLevel)")
{
ObjectConstructor.Instance.Art.gameObject.SetActive(true);
}
if (((object)RoundManager.Instance.currentLevel).ToString() == "AssuranceLevel (SelectableLevel)")
{
ObjectConstructor.Instance.Ass.gameObject.SetActive(true);
}
if (((object)RoundManager.Instance.currentLevel).ToString() == "CompanyBuildingLevel (SelectableLevel)")
{
ObjectConstructor.Instance.Com.gameObject.SetActive(true);
}
if (((object)RoundManager.Instance.currentLevel).ToString() == "ExperimentationLevel (SelectableLevel)")
{
ObjectConstructor.Instance.Exp.gameObject.SetActive(true);
}
}
[Obsolete("Method unsafe", true)]
public static void ForceDestroySpawnedObjects()
{
try
{
Object.Destroy((Object)(object)ObjectConstructor.Instance.ArtBillboard.gameObject);
Object.Destroy((Object)(object)ObjectConstructor.Instance.AssBillboard.gameObject);
Object.Destroy((Object)(object)ObjectConstructor.Instance.CompBillboard.gameObject);
Object.Destroy((Object)(object)ObjectConstructor.Instance.ExpBillboard.gameObject);
}
catch (Exception arg)
{
Plugin.logger.LogError((object)$"Failed to run ForceDestroySpawnedObjects() Exception: {arg}");
}
}
[Obsolete("It doesnt work, i have no idea why the fuck its not working", true)]
public void ForceDestroySpawnedObjectsConditional()
{
try
{
if ((Object)(object)ObjectConstructor.Instance.ArtBillboard.gameObject != (Object)null)
{
Object.Destroy((Object)(object)ObjectConstructor.Instance.ArtBillboard.gameObject);
}
if ((Object)(object)ObjectConstructor.Instance.AssBillboard.gameObject != (Object)null)
{
Object.Destroy((Object)(object)ObjectConstructor.Instance.AssBillboard.gameObject);
}
if ((Object)(object)ObjectConstructor.Instance.CompBillboard.gameObject != (Object)null)
{
Object.Destroy((Object)(object)ObjectConstructor.Instance.CompBillboard.gameObject);
}
if ((Object)(object)ObjectConstructor.Instance.ExpBillboard.gameObject != (Object)null)
{
Object.Destroy((Object)(object)ObjectConstructor.Instance.ExpBillboard.gameObject);
}
}
catch (Exception arg)
{
Plugin.logger.LogError((object)$"Failed to run ForceDestroySpawnedObjectsConditional() Exception: {arg}");
}
}
}
[HarmonyPatch]
public class ManagerPatchClasses : MonoBehaviour
{
[HarmonyPrefix]
[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
private static void OnShipLeave()
{
DependantStaticLeave();
}
[HarmonyPrefix]
[HarmonyPatch(typeof(StartOfRound), "StartGame")]
private static void OnGameStart()
{
OnGameStartStatic();
}
[HarmonyPrefix]
[HarmonyPatch(typeof(TimeOfDay), "Start")]
private static void OnTimeOfDayStart()
{
OnTimeOfDayStartStatic();
}
public static void DependantStaticLeave()
{
if (MeltdownHandler.HasMeltdownStarted)
{
NetworkHandler.SwitchMeltdownBillboardServerMessage.SendAllClients(0, true);
OnShipLeaveStatic();
MeltdownHandler.HasMeltdownStarted = false;
}
else if (!MeltdownHandler.HasMeltdownStarted)
{
OnShipLeaveStatic();
}
}
public static void OnShipLeaveStatic()
{
if (!NetworkManager.Singleton.IsHost)
{
return;
}
try
{
if (((object)RoundManager.Instance.currentLevel).ToString() == "ArtificeLevel (SelectableLevel)")
{
NetworkHandler.DeSpawnBillboardServerMessage.SendAllClients(0, true);
}
else if (((object)RoundManager.Instance.currentLevel).ToString() == "AssuranceLevel (SelectableLevel)")
{
NetworkHandler.DeSpawnBillboardServerMessage.SendAllClients(1, true);
}
else if (((object)RoundManager.Instance.currentLevel).ToString() == "CompanyBuildingLevel (SelectableLevel)")
{
NetworkHandler.DeSpawnBillboardServerMessage.SendAllClients(2, true);
}
else if (((object)RoundManager.Instance.currentLevel).ToString() == "ExperimentationLevel (SelectableLevel)")
{
NetworkHandler.DeSpawnBillboardServerMessage.SendAllClients(3, true);
}
}
catch (Exception arg)
{
Plugin.logger.LogError((object)$" Failed to run OnGameStartStatic Exception: {arg}");
}
Plugin.logger.LogDebug((object)"ShipLeave");
}
public static void OnGameStartStatic()
{
if (!NetworkManager.Singleton.IsHost)
{
return;
}
try
{
if (((object)RoundManager.Instance.currentLevel).ToString() == "ArtificeLevel (SelectableLevel)")
{
NetworkHandler.SpawnBillboardServerMessage.SendAllClients(0, true);
}
else if (((object)RoundManager.Instance.currentLevel).ToString() == "AssuranceLevel (SelectableLevel)")
{
NetworkHandler.SpawnBillboardServerMessage.SendAllClients(1, true);
}
else if (((object)RoundManager.Instance.currentLevel).ToString() == "CompanyBuildingLevel (SelectableLevel)")
{
NetworkHandler.SpawnBillboardServerMessage.SendAllClients(2, true);
}
else if (((object)RoundManager.Instance.currentLevel).ToString() == "ExperimentationLevel (SelectableLevel)")
{
NetworkHandler.SpawnBillboardServerMessage.SendAllClients(3, true);
}
}
catch (Exception arg)
{
Plugin.logger.LogError((object)$" Failed to run OnGameStartStatic Exception: {arg}");
}
Plugin.logger.LogDebug((object)"GameStart");
}
public static void OnTimeOfDayStartStatic()
{
try
{
try
{
if ((Object)(object)ObjectConstructor.ConstructorObj == (Object)null)
{
ObjectConstructor.SpawnFramework();
}
else
{
Plugin.logger.LogWarning((object)"Constructor was already spawned, aborting spawning duplicates to prevent errors");
}
}
catch (Exception arg)
{
Plugin.logger.LogWarning((object)$"Failed to spawn ConstructorObject {arg}");
}
}
catch (Exception arg2)
{
Plugin.logger.LogError((object)$"Failed to run OnTimeOfDayStartStatic() {arg2}");
}
Plugin.logger.LogDebug((object)"TimeOfDayStart");
}
public static void SwitchMeltdownContent(int switchToMeltdown)
{
bool flag = false;
switch (switchToMeltdown)
{
case 0:
flag = false;
break;
case 1:
flag = true;
break;
}
if (((object)RoundManager.Instance.currentLevel).ToString() == "ArtificeLevel (SelectableLevel)")
{
ObjectConstructor.Instance.ArtBillboardContent.SetActive(!flag);
ObjectConstructor.Instance.ArtBillboardMeltdownContent.SetActive(flag);
}
else if (((object)RoundManager.Instance.currentLevel).ToString() == "AssuranceLevel (SelectableLevel)")
{
ObjectConstructor.Instance.AssBillboardContent.SetActive(!flag);
ObjectConstructor.Instance.AssBillboardMeltdownContent.SetActive(flag);
}
else if (((object)RoundManager.Instance.currentLevel).ToString() == "CompanyBuildingLevel (SelectableLevel)")
{
ObjectConstructor.Instance.CompBillboardContent.SetActive(!flag);
ObjectConstructor.Instance.CompBillboardMeltdownContent.SetActive(flag);
}
else if (((object)RoundManager.Instance.currentLevel).ToString() == "ExperimentationLevel (SelectableLevel)")
{
ObjectConstructor.Instance.ExpBillboardContent.SetActive(!flag);
ObjectConstructor.Instance.ExpBillboardMeltdownContent.SetActive(flag);
}
}
public static void ArtificeBillboardClientSpawn(int data)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
GameObject obj = Content.AssetsList[data];
Vector3 position = Content.AssetsList[data].transform.position;
Quaternion rotation = Content.AssetsList[data].transform.rotation;
GameObject val = Object.Instantiate<GameObject>(obj, position, ((Quaternion)(ref rotation)).normalized, Content.AssetsList[data].transform.parent);
}
public static void ArtificeBillboardClientDeSpawn(int data)
{
switch (data)
{
case 0:
Object.Destroy((Object)(object)ObjectConstructor.Instance.ArtBillboard.gameObject);
break;
case 1:
Object.Destroy((Object)(object)ObjectConstructor.Instance.AssBillboard.gameObject);
break;
case 2:
Object.Destroy((Object)(object)ObjectConstructor.Instance.CompBillboard.gameObject);
break;
case 3:
Object.Destroy((Object)(object)ObjectConstructor.Instance.ExpBillboard.gameObject);
break;
}
}
}
[HarmonyPatch]
internal class NetworkHandler
{
public static bool NetworkHandlersRegistered = false;
public static LethalServerMessage<int> SpawnBillboardServerMessage = new LethalServerMessage<int>("SPAWN_BILLBOARD", (Action<int, ulong>)null);
public static LethalClientMessage<int> SpawnBillboardClientMessage = new LethalClientMessage<int>("SPAWN_BILLBOARD", (Action<int>)null, (Action<int, ulong>)null);
public static LethalServerMessage<int> DeSpawnBillboardServerMessage = new LethalServerMessage<int>("DESPAWN_BILLBOARD", (Action<int, ulong>)null);
public static LethalClientMessage<int> DeSpawnBillboardClientMessage = new LethalClientMessage<int>("DESPAWN_BILLBOARD", (Action<int>)null, (Action<int, ulong>)null);
public static LethalServerMessage<int> SwitchMeltdownBillboardServerMessage = new LethalServerMessage<int>("SWITCH_BILLBOARD", (Action<int, ulong>)null);
public static LethalClientMessage<int> SwitchMeltdownBillboardClientMessage = new LethalClientMessage<int>("SWITCH_BILLBOARD", (Action<int>)null, (Action<int, ulong>)null);
[HarmonyPostfix]
[HarmonyPatch(typeof(StartOfRound), "Start")]
public static void RegisterNetworkHandlers()
{
if (NetworkHandlersRegistered)
{
return;
}
try
{
SpawnBillboardServerMessage.OnReceived += SpawnBillboardNetworkHandlerServer;
SpawnBillboardClientMessage.OnReceived += SpawnBillboardNetworkHandler;
DeSpawnBillboardServerMessage.OnReceived += DeSpawnBillboardNetworkHandlerServer;
DeSpawnBillboardClientMessage.OnReceived += DeSpawnBillboardNetworkHandler;
SwitchMeltdownBillboardServerMessage.OnReceived += SwitchMeltdownBillboardNetworkHandlerServer;
SwitchMeltdownBillboardClientMessage.OnReceived += SwitchMeltdownBillboardNetworkHandler;
NetworkHandlersRegistered = true;
}
catch (Exception arg)
{
Plugin.logger.LogFatal((object)$"Failed to register network handlers, Billboards mod can NOT continue... UnPatching everything! Exception: {arg}");
HUDManager.Instance.DisplayTip("Fatal Error", "Failed to register network handlers, UnPatching!", true, false, "LC_Tip1");
Harmony.UnpatchAll();
}
finally
{
if (NetworkHandlersRegistered)
{
Plugin.logger.LogDebug((object)"Registered network handlers!");
}
}
}
public static void SpawnBillboardNetworkHandler(int data)
{
Plugin.logger.LogWarning((object)$"Received network message for spawn billboard result: {data}");
HandleSpawnBillboard(data);
}
public static void SpawnBillboardNetworkHandlerServer(int data, ulong empty)
{
Plugin.logger.LogWarning((object)$"Received network message for spawn billboard result: {data}");
HandleSpawnBillboard(data);
}
public static void HandleSpawnBillboard(int data)
{
ManagerPatchClasses.ArtificeBillboardClientSpawn(data);
}
public static void DeSpawnBillboardNetworkHandler(int data)
{
Plugin.logger.LogWarning((object)$"Received network message for despawn billboard result: {data}");
HandleDeSpawnBillboar(data);
}
public static void DeSpawnBillboardNetworkHandlerServer(int data, ulong empty)
{
Plugin.logger.LogWarning((object)$"Received network message for despawn billboard result: {data}");
HandleDeSpawnBillboar(data);
}
public static void HandleDeSpawnBillboar(int data)
{
ManagerPatchClasses.ArtificeBillboardClientDeSpawn(data);
}
public static void SwitchMeltdownBillboardNetworkHandler(int data)
{
Plugin.logger.LogWarning((object)$"Received network message for switch billboard content result: {data}");
HandleSwitchMeltdownBillboar(data);
}
public static void SwitchMeltdownBillboardNetworkHandlerServer(int data, ulong empty)
{
Plugin.logger.LogWarning((object)$"Received network message for switch billboard content result: {data}");
HandleSwitchMeltdownBillboar(data);
}
public static void HandleSwitchMeltdownBillboar(int data)
{
ManagerPatchClasses.SwitchMeltdownContent(data);
}
}
public class ObjectConstructor : MonoBehaviour
{
[SerializeField]
public GameObject Art;
[SerializeField]
public GameObject Ass;
[SerializeField]
public GameObject Exp;
[SerializeField]
public GameObject Com;
[SerializeField]
public static GameObject Inst;
public static ObjectConstructor Instance { get; private set; }
internal GameObject ArtBillboard => GameObject.Find("/Bbilboard(Clone)");
internal GameObject AssBillboard => GameObject.Find("/BbilboardAss(Clone)");
internal GameObject ExpBillboard => GameObject.Find("/BbilboardExper(Clone)");
internal GameObject CompBillboard => GameObject.Find("/BbilboardCompany(Clone)");
internal static GameObject ConstructorObj => GameObject.Find("/BbilboardFrameworkConstructor(Clone)");
internal GameObject AssBillboardContent => GameObject.Find("/BbilboardAss(Clone)/Cube/Content");
internal GameObject AssBillboardMeltdownContent => GameObject.Find("/BbilboardAss(Clone)/Cube/MeltdownContent");
internal GameObject ArtBillboardContent => GameObject.Find("/Bbilboard(Clone)/Cube/Content");
internal GameObject ArtBillboardMeltdownContent => GameObject.Find("/Bbilboard(Clone)/Cube/MeltdownContent");
internal GameObject ExpBillboardContent => GameObject.Find("/BbilboardExper(Clone)/Cube/Content");
internal GameObject ExpBillboardMeltdownContent => GameObject.Find("/BbilboardExper(Clone)/Cube/MeltdownContent");
internal GameObject CompBillboardContent => GameObject.Find("/BbilboardCompany(Clone)/Cube/Content");
internal GameObject CompBillboardMeltdownContent => GameObject.Find("/BbilboardCompany(Clone)/Cube/MeltdownContent");
private void Awake1()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
}
private void Awake()
{
Awake1();
if ((Object)(object)Art == (Object)null)
{
Plugin.logger.LogDebug((object)"Art reference is null");
}
else if ((Object)(object)Art != (Object)null)
{
Plugin.logger.LogDebug((object)"Art reference is NOT null");
}
if ((Object)(object)Ass == (Object)null)
{
Plugin.logger.LogDebug((object)"Ass reference is null");
}
else if ((Object)(object)Ass != (Object)null)
{
Plugin.logger.LogDebug((object)"Ass reference is NOT null");
}
if ((Object)(object)Instance == (Object)null)
{
Plugin.logger.LogDebug((object)"Instance reference is null");
}
else if ((Object)(object)Instance != (Object)null)
{
Plugin.logger.LogDebug((object)"Instance reference is NOT null");
}
}
public static void SpawnFramework()
{
if (0 == 0)
{
GameObject val = Object.Instantiate<GameObject>(Content.AssetsList[4]);
bool flag = true;
}
InstantiateObject();
}
public static void InstantiateObject()
{
try
{
if ((Object)(object)Instance == (Object)null)
{
Instance = Instance;
}
}
catch (Exception ex)
{
Plugin.logger.LogError((object)ex);
}
}
internal static void ExternalAwake()
{
Instance.Awake();
}
[Obsolete("Do NOT use", false)]
internal GameObject GetGameObject(string path)
{
return GameObject.Find(path);
}
}
[RequireComponent(typeof(InteractTrigger))]
public class PowerBoxHittable : MonoBehaviour, IHittable
{
private bool Interacted = false;
private InteractTrigger interactTrigger;
public bool Hit(int force, Vector3 hitDirection, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
Landmine val = new Landmine();
val.ExplodeMineServerRpc();
Plugin.logger.LogError((object)"Explode");
return false;
}
public void OnInteract()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
Landmine val = new Landmine();
val.ExplodeMineServerRpc();
}
}
}
namespace Billboards.NetcodePatcher
{
[AttributeUsage(AttributeTargets.Module)]
internal class NetcodePatchedAssemblyAttribute : Attribute
{
}
}