Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Polyhydra Games Valheim Mod v1.0.1
PolyhydraGames.Valheim.Plugin.dll
Decompiled 6 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using HarmonyLib; using JetBrains.Annotations; using Jotunn; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using PolyhydraGames.Valheim.Plugin.Commands; using PolyhydraGames.Valheim.Plugin.Extensions; using PolyhydraGames.Valheim.Plugin.Models; using Splatform; using UnityEngine; using UnityEngine.Networking; using ValheimRcon; using ValheimRcon.Commands; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("PolyhydraGames.Valheim.Plugin")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+329e48f7eebbe7e69b8df0f0bcb4fcad6b6cbfe7")] [assembly: AssemblyProduct("PolyhydraGames.Valheim.Plugin")] [assembly: AssemblyTitle("PolyhydraGames.Valheim.Plugin")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } public class IsExternalInit { } } namespace PolyhydraGames.Valheim.Plugin { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.polyhydragames.rcon", "Polyhydra Games Mods", "1.0.0")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private readonly Harmony _harmony = new Harmony("com.polyhydragames.rcon"); public const string Guid = "com.polyhydragames.rcon"; public const string Name = "Polyhydra Games Mods"; public const string Version = "1.0.0"; private void Awake() { _harmony.PatchAll(); try { RconCommandsUtil.RegisterAllCommands(Assembly.GetExecutingAssembly()); Logger.LogInfo((object)"[PolyValheimRcon] Loaded"); } catch (Exception ex) { Logger.LogWarning((object)("[PolyValheimRcon] Loading failed, hopefully this isn't the server!\n" + ex.Message)); } } } } namespace PolyhydraGames.Valheim.Plugin.Whisper { [HarmonyPatch(typeof(Game))] public static class WhisperRpc { [HarmonyPostfix] [HarmonyPatch("Start")] private static void Register() { Logger.LogInfo((object)"Registered ShakeRpc"); ZRoutedRpc.instance.Register<string, string>("Whisper", (Action<long, string, string>)Whisper); } private static void Whisper(long sender, string name, string message) { Logger.LogInfo((object)("Received Whisper, name: " + name + " message: " + message)); if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)GameCamera.instance == (Object)null) { return; } try { ((Terminal)Chat.instance).AddString(name, message, (Type)1, false); Helpers.ShowPopup((MessageType)1, name + ": " + message); Logger.LogInfo((object)"Whisper shake triggered with amount "); } catch (Exception ex) { Logger.LogInfo((object)("Screen shake failed. " + ex.Message)); } } } internal class Whisper : PolyRconCommand { public override string Command => "whisper"; public override string Description => "Whisper a player."; public override string Method => "Whisper"; private string ProcessCommand(PlayerWrapperType player, CommandArgs args) { string @string = args.GetString(1); string remainingString = args.GetRemainingString(2); InvokeRouted(player, @string, remainingString); return "Applied Whisper to " + player.Name; } protected override string OnHandle(PlayerWrapperType player, CommandArgs args) { return (args.Arguments.Count < 3) ? "Usage: whisper <player> <name> <message> " : ProcessCommand(player, args); } } public static class Metadata { public const string TestString = "whisper 76561197962914477 Dan Howdy ho"; public const string RCPCall = "Whisper"; public const string Command = "whisper"; public const string Description = "Whisper a player."; public const string Usage = "Usage: whisper <player> <name> <message> "; public const int MinimumParameters = 3; } } namespace PolyhydraGames.Valheim.Plugin.Smite { [HarmonyPatch(typeof(Game))] public static class SmiteRPC { [HarmonyPostfix] [HarmonyPatch("Start")] private static void RegisterRpc() { Logger.LogInfo((object)"Registered SmiteRPC"); ZRoutedRpc.instance.Register("Smite", (Action<long>)SmiteAction); } private static void SmiteAction(long _) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) Logger.LogInfo((object)"Received request to Smite"); ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { Logger.LogWarning((object)"No ZNetScene available yet!"); return; } Vector3 position = ((Component)Player.m_localPlayer).transform.position; string[] names = new string[3] { "lightningAOE", "vfx_lightning_hit", "fx_thunder" }; var (flag, text, text2) = TrySpawnFirstNetworked(instance, position, Quaternion.identity, names); if (flag) { Logger.LogInfo((object)("Smite spawned prefab " + text)); } else { Logger.LogWarning((object)("Smite failed: " + text2)); } } private static (bool ok, string used, string reason) TrySpawnFirstNetworked(ZNetScene zns, Vector3 pos, Quaternion rot, string[] names) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) foreach (string text in names) { GameObject prefab = zns.GetPrefab(text); if ((Object)(object)prefab == (Object)null) { continue; } ZNetView component = prefab.GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null)) { GameObject val = Object.Instantiate<GameObject>(prefab, pos, rot); TimedDestruction component2 = val.GetComponent<TimedDestruction>(); if ((Object)(object)component2 == (Object)null) { Object.Destroy((Object)(object)val, 5f); } return (true, text, ""); } } return (false, "", "no networked prefabs among: " + string.Join(", ", names)); } } internal class Smite : PolyRconCommand { public override string Command => "smite"; public override string Description => "smite a player."; public override string Method => "Smite"; protected override string OnHandle(PlayerWrapperType player, CommandArgs args) { if (args.Arguments.Count < 2) { return "Usage: smite <player> <powerName> "; } string @string = args.GetString(1); InvokeRouted(player, @string); return "Smote '" + @string + "'"; } } public static class Metadata { public const string RCPCall = "Smite"; public const string Command = "smite"; public const string Description = "smite a player."; public const string Usage = "Usage: smite <player> <powerName> "; public const int MinimumParameters = 2; } } namespace PolyhydraGames.Valheim.Plugin.Shake { [HarmonyPatch(typeof(Game))] public static class ShakeRpc { [HarmonyPostfix] [HarmonyPatch("Start")] private static void Register() { Logger.LogInfo((object)"Registered ShakeRpc"); ZRoutedRpc.instance.Register<string>("Shake", (Action<long, string>)Shake); } private static void Shake(long sender, string shake) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) Logger.LogInfo((object)("Received Screen Shake, amount: " + shake)); if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)GameCamera.instance == (Object)null) { return; } try { float num = 10f; float num2 = float.Parse(shake); Vector3 position = Player.m_localPlayer.GetPosition(); GameCamera.instance.AddShake(position, num, num2, false); Logger.LogInfo((object)$"Screen shake triggered with amount {num2}"); } catch (Exception ex) { Logger.LogInfo((object)("Screen shake failed. " + ex.Message)); } } } internal class Shake : PolyRconCommand { public override string Command => "shake"; public override string Description => "Shake a player."; public override string Method => "Shake"; private string ProcessCommand(PlayerWrapperType player, CommandArgs args) { string @string = args.GetString(1); InvokeRouted(player, @string); return "Applied shake " + @string + " to " + player.Name; } protected override string OnHandle(PlayerWrapperType player, CommandArgs args) { return (args.Arguments.Count < 2) ? "Usage: shake <player> <amount> " : ProcessCommand(player, args); } } public static class Metadata { public const string TestString = "shake 76561197962914477 5"; public const string RCPCall = "Shake"; public const string Command = "shake"; public const string Description = "Shake a player."; public const string Usage = "Usage: shake <player> <amount> "; public const int MinimumParameters = 2; } } namespace PolyhydraGames.Valheim.Plugin.Models { public class AudioHelper : MonoBehaviour { [CompilerGenerated] private sealed class <PlayAudioFromUrl>d__0 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string url; public Vector3 position; public AudioHelper <>4__this; private AudioType <audioType>5__1; private UnityWebRequest <www>5__2; private AudioClip <clip>5__3; private GameObject <audioObject>5__4; private AudioSource <audioSource>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PlayAudioFromUrl>d__0(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <www>5__2 = null; <clip>5__3 = null; <audioObject>5__4 = null; <audioSource>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <audioType>5__1 = (AudioType)(url.Contains(".mp3") ? 13 : 20); <www>5__2 = UnityWebRequestMultimedia.GetAudioClip(url, <audioType>5__1); <>1__state = -3; <>2__current = <www>5__2.SendWebRequest(); <>1__state = 1; return true; case 1: <>1__state = -3; if ((int)<www>5__2.result != 1) { Debug.LogWarning((object)("Failed to download audio: " + <www>5__2.error)); } else { <clip>5__3 = DownloadHandlerAudioClip.GetContent(<www>5__2); <audioObject>5__4 = new GameObject("TempAudio"); <audioObject>5__4.transform.position = position; <audioSource>5__5 = <audioObject>5__4.AddComponent<AudioSource>(); <audioSource>5__5.clip = <clip>5__3; <audioSource>5__5.spatialBlend = 1f; <audioSource>5__5.Play(); Object.Destroy((Object)(object)<audioObject>5__4, <clip>5__3.length); <clip>5__3 = null; <audioObject>5__4 = null; <audioSource>5__5 = null; } <>m__Finally1(); <www>5__2 = null; return false; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<www>5__2 != null) { ((IDisposable)<www>5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [IteratorStateMachine(typeof(<PlayAudioFromUrl>d__0))] public IEnumerator PlayAudioFromUrl(string url, Vector3 position) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PlayAudioFromUrl>d__0(0) { <>4__this = this, url = url, position = position }; } } public class CoroutineRunner : MonoBehaviour { private static CoroutineRunner _instance; public static CoroutineRunner Instance { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("CoroutineRunner"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<CoroutineRunner>(); } return _instance; } } public void Run(IEnumerator routine) { ((MonoBehaviour)this).StartCoroutine(routine); } } public record PlayerWrapperType(ZNetPeer Peer, ZDO Zdo) { public ZRpc RPC => Peer.m_rpc; public long ZDOID => Peer.m_uid; public string Name => Peer.m_playerName; public ZDOID PlayerId => Peer.m_characterID; public string Info => PlayerUtils.GetPlayerInfo(Peer); public Vector3 RefPosition => Peer.GetRefPos(); public string SocketEndpoint { get { ISocket socket = Peer.m_socket; return (socket != null) ? socket.GetEndPointString() : null; } } public ZDOID ZdoUid => Zdo.m_uid; public Vector3 WorldPosition => Zdo.GetPosition(); public Quaternion Rotation => Zdo.GetRotation(); public long UnderlyingUid => Zdo.GetLong(ZDOVars.s_playerID, 0L); public long Owner => Zdo.GetOwner(); public void PeerInvoke(string method, params object[] args) { RPC.Invoke(method, args); } public override string ToString() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return $"{Name} [{ZDOID}] at {RefPosition}"; } [CompilerGenerated] protected virtual bool PrintMembers(StringBuilder builder) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) RuntimeHelpers.EnsureSufficientExecutionStack(); builder.Append("Peer = "); builder.Append(Peer); builder.Append(", Zdo = "); builder.Append(Zdo); builder.Append(", RPC = "); builder.Append(RPC); builder.Append(", ZDOID = "); builder.Append(ZDOID.ToString()); builder.Append(", Name = "); builder.Append((object?)Name); builder.Append(", PlayerId = "); ZDOID val = PlayerId; builder.Append(((object)(ZDOID)(ref val)).ToString()); builder.Append(", Info = "); builder.Append((object?)Info); builder.Append(", RefPosition = "); Vector3 val2 = RefPosition; builder.Append(((object)(Vector3)(ref val2)).ToString()); builder.Append(", SocketEndpoint = "); builder.Append((object?)SocketEndpoint); builder.Append(", ZdoUid = "); val = ZdoUid; builder.Append(((object)(ZDOID)(ref val)).ToString()); builder.Append(", WorldPosition = "); val2 = WorldPosition; builder.Append(((object)(Vector3)(ref val2)).ToString()); builder.Append(", Rotation = "); Quaternion rotation = Rotation; builder.Append(((object)(Quaternion)(ref rotation)).ToString()); builder.Append(", UnderlyingUid = "); builder.Append(UnderlyingUid.ToString()); builder.Append(", Owner = "); builder.Append(Owner.ToString()); return true; } } } namespace PolyhydraGames.Valheim.Plugin.Extensions { public static class Helpers { public static void ShowPopup(MessageType msgType, string message) { MessageHud.instance.ShowMessage((MessageType)1, message, 0, (Sprite)null, false); } [CanBeNull] public static StatusEffect GetEffect(string statusName) { int stableHashCode = statusName.GetStableHashCode(); StatusEffect val = ObjectDB.instance.GetStatusEffect(stableHashCode); if ((Object)(object)val == (Object)null) { val = ((IEnumerable<StatusEffect>)ObjectDB.instance.m_StatusEffects).FirstOrDefault((Func<StatusEffect, bool>)((StatusEffect se) => ((Object)se).name.Equals(statusName, StringComparison.OrdinalIgnoreCase))); if ((Object)(object)val == (Object)null) { string text = "No effect found for " + statusName + "Effects: " + string.Join(", ", ObjectDB.instance.m_StatusEffects.Select((StatusEffect x) => ((Object)x).name)); Logger.LogWarning((object)text); } } return val; } public static bool IsDedicatedServer() { bool result = Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsDedicated(); Logger.LogInfo((object)("[IsDedicated] " + result)); return result; } public static string GetRpcCommandName(this RpcCommand command) { string value; return RpcCommandMap.Names.TryGetValue(command, out value) ? value : "RPC_Unknown"; } public static string GetRemainingString(this CommandArgs args, int index) { return string.Join(" ", args.Arguments.Skip(index)); } public static string GetPlayerInfo() { string[] value = (from x in Player.GetAllPlayers() select x.GetPlayerID() + " - " + x.GetPlayerName()).ToArray(); return string.Join("\n", value); } public static void ListPrefabs() { if ((Object)(object)ZNetScene.instance == (Object)null) { ZLog.Log((object)"ZNetScene not ready yet."); return; } List<string> prefabNames = ZNetScene.instance.GetPrefabNames(); foreach (string item in prefabNames) { ZLog.Log((object)("Prefab: " + item)); } ZLog.Log((object)$"Total prefabs: {prefabNames.Count}"); } public static List<string> GetEnvironmentNames() { List<string> result = null; if ((Object)(object)EnvMan.instance == (Object)null) { ZLog.Log((object)"ZNetScene not ready yet."); return result; } List<string> list = EnvMan.instance.m_environments.Select((EnvSetup e) => e.m_name).ToList(); foreach (string item in list) { ZLog.Log((object)("Environment: " + item)); } ZLog.Log((object)$"Total environments: {list.Count}"); return list; } } public static class PlayerWrapper { public static Vector3 GetPosition(this Player player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return ((Component)player).transform.position; } public static PlayerWrapperType Create(ZNetPeer peer) { return new PlayerWrapperType(peer, PlayerUtils.GetZDO(peer)); } public static void InvokeRoutedRpcOnWorld(this PlayerWrapperType player, RpcCommand rpc, params object[] args) { ZRoutedRpc.instance.InvokeRoutedRPC(player.Owner, rpc.GetRpcCommandName(), args); } public static void InvokeRoutedRpc(this PlayerWrapperType player, ZDOID target, RpcCommand rpc, params object[] args) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) ZRoutedRpc.instance.InvokeRoutedRPC(player.Owner, target, rpc.GetRpcCommandName(), args); } public static void InvokeRoutedRpcOnSelf(this PlayerWrapperType player, RpcCommand rpc, params object[] args) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) player.InvokeRoutedRpc(player.PlayerId, rpc, args); } public static ZDO GetZDO(this PlayerWrapperType player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return ZDOMan.instance.GetZDO(player.PlayerId); } public static string GetSteamId(this PlayerWrapperType player) { return player.RPC.GetSocket().GetHostName(); } } public enum RpcCommand { SetGuardianPower, UseGuardianPower, PeerInfo, NetTime, ServerHandshake, ClientHandshake, ServerSyncedPlayerData, Disconnect, Error, Kick, Kicked, Ban, Unban, AdminList, Save, SavePlayerProfile, PlayerList, PrintBanned, RemoteCommand, RemotePrint, SpawnObject, DestroyZDO, RequestZDO, ZDOData, RoutedRPC, SetTrigger, Heal, Damage, Stagger, UseStamina, OnDeath, OnTargeted, FlashShield, AddStatusEffect, Controls, ReleaseControl, RequestControl, RequestRespons, ChatMessage, TeleportPlayer, Say, DropItem, DropItemByName, RequestOwn, SetPose, SetVisualItem, OpenRespons, RequestStack, StackResponse, RequestOpen, RequestTakeAll, TakeAllRespons, AddFuel, AddItem, RemoveDoneItem, SetSlotVisual, AddFuelAmount, SetFuelAmount, ToggleOn, Pickup, RequestPickup, UseDoor, Repair, Remove, HealthChanged, UpdateMaterial, SetAreaHealth, SetEvent, BossSpawnInitiated, RemoveBossSpawnInventoryItems, SpawnBoss, SetTamed, ResetCloth, FreezeFrame, OnHit, Attach, TeleportTo, StaggerCreature, OnEat, TryEat, EatConfirmation, Nibble, Step, Wakeup, Grow, Shake, Command, UnSummon, SetName, Forward, Backward, Rudder, Stop, AddSaddle, RemoveSaddle, SetSaddle, RequestControlShip, ReleaseControlShip, SetGlobalKey, RemoveGlobalKey, GlobalKeys, LocationIcons, AddNoise } public static class RpcCommandMap { public static readonly Dictionary<RpcCommand, string> Names = new Dictionary<RpcCommand, string> { { RpcCommand.SetGuardianPower, "RPC_SetGuardianPower" }, { RpcCommand.UseGuardianPower, "RPC_UseGuardianPower" }, { RpcCommand.PeerInfo, "RPC_PeerInfo" }, { RpcCommand.NetTime, "RPC_NetTime" }, { RpcCommand.ServerHandshake, "RPC_ServerHandshake" }, { RpcCommand.ClientHandshake, "RPC_ClientHandshake" }, { RpcCommand.ServerSyncedPlayerData, "RPC_ServerSyncedPlayerData" }, { RpcCommand.Disconnect, "RPC_Disconnect" }, { RpcCommand.Error, "RPC_Error" }, { RpcCommand.Kick, "RPC_Kick" }, { RpcCommand.Kicked, "RPC_Kicked" }, { RpcCommand.Ban, "RPC_Ban" }, { RpcCommand.Unban, "RPC_Unban" }, { RpcCommand.AdminList, "RPC_AdminList" }, { RpcCommand.Save, "RPC_Save" }, { RpcCommand.SavePlayerProfile, "RPC_SavePlayerProfile" }, { RpcCommand.PlayerList, "RPC_PlayerList" }, { RpcCommand.PrintBanned, "RPC_PrintBanned" }, { RpcCommand.RemoteCommand, "RPC_RemoteCommand" }, { RpcCommand.RemotePrint, "RPC_RemotePrint" }, { RpcCommand.SpawnObject, "RPC_SpawnObject" }, { RpcCommand.DestroyZDO, "RPC_DestroyZDO" }, { RpcCommand.RequestZDO, "RPC_RequestZDO" }, { RpcCommand.ZDOData, "RPC_ZDOData" }, { RpcCommand.RoutedRPC, "RPC_RoutedRPC" }, { RpcCommand.SetTrigger, "RPC_SetTrigger" }, { RpcCommand.Heal, "RPC_Heal" }, { RpcCommand.Damage, "RPC_Damage" }, { RpcCommand.Stagger, "RPC_Stagger" }, { RpcCommand.UseStamina, "RPC_UseStamina" }, { RpcCommand.OnDeath, "RPC_OnDeath" }, { RpcCommand.OnTargeted, "RPC_OnTargeted" }, { RpcCommand.FlashShield, "RPC_FlashShield" }, { RpcCommand.AddStatusEffect, "RPC_AddStatusEffect" }, { RpcCommand.Controls, "RPC_Controls" }, { RpcCommand.ReleaseControl, "RPC_ReleaseControl" }, { RpcCommand.RequestControl, "RPC_RequestControl" }, { RpcCommand.RequestRespons, "RPC_RequestRespons" }, { RpcCommand.ChatMessage, "RPC_ChatMessage" }, { RpcCommand.TeleportPlayer, "RPC_TeleportPlayer" }, { RpcCommand.Say, "RPC_Say" }, { RpcCommand.DropItem, "RPC_DropItem" }, { RpcCommand.DropItemByName, "RPC_DropItemByName" }, { RpcCommand.RequestOwn, "RPC_RequestOwn" }, { RpcCommand.SetPose, "RPC_SetPose" }, { RpcCommand.SetVisualItem, "RPC_SetVisualItem" }, { RpcCommand.OpenRespons, "RPC_OpenRespons" }, { RpcCommand.RequestStack, "RPC_RequestStack" }, { RpcCommand.StackResponse, "RPC_StackResponse" }, { RpcCommand.RequestOpen, "RPC_RequestOpen" }, { RpcCommand.RequestTakeAll, "RPC_RequestTakeAll" }, { RpcCommand.TakeAllRespons, "RPC_TakeAllRespons" }, { RpcCommand.AddFuel, "RPC_AddFuel" }, { RpcCommand.AddItem, "RPC_AddItem" }, { RpcCommand.RemoveDoneItem, "RPC_RemoveDoneItem" }, { RpcCommand.SetSlotVisual, "RPC_SetSlotVisual" }, { RpcCommand.AddFuelAmount, "RPC_AddFuelAmount" }, { RpcCommand.SetFuelAmount, "RPC_SetFuelAmount" }, { RpcCommand.ToggleOn, "RPC_ToggleOn" }, { RpcCommand.Pickup, "RPC_Pickup" }, { RpcCommand.RequestPickup, "RPC_RequestPickup" }, { RpcCommand.UseDoor, "RPC_UseDoor" }, { RpcCommand.Repair, "RPC_Repair" }, { RpcCommand.Remove, "RPC_Remove" }, { RpcCommand.HealthChanged, "RPC_HealthChanged" }, { RpcCommand.UpdateMaterial, "RPC_UpdateMaterial" }, { RpcCommand.SetAreaHealth, "RPC_SetAreaHealth" }, { RpcCommand.SetEvent, "RPC_SetEvent" }, { RpcCommand.BossSpawnInitiated, "RPC_BossSpawnInitiated" }, { RpcCommand.RemoveBossSpawnInventoryItems, "RPC_RemoveBossSpawnInventoryItems" }, { RpcCommand.SpawnBoss, "RPC_SpawnBoss" }, { RpcCommand.SetTamed, "RPC_SetTamed" }, { RpcCommand.ResetCloth, "RPC_ResetCloth" }, { RpcCommand.FreezeFrame, "RPC_FreezeFrame" }, { RpcCommand.OnHit, "RPC_OnHit" }, { RpcCommand.Attach, "RPC_Attach" }, { RpcCommand.TeleportTo, "RPC_TeleportTo" }, { RpcCommand.StaggerCreature, "RPC_Stagger" }, { RpcCommand.OnEat, "RPC_OnEat" }, { RpcCommand.TryEat, "RPC_TryEat" }, { RpcCommand.EatConfirmation, "RPC_EatConfirmation" }, { RpcCommand.Nibble, "RPC_Nibble" }, { RpcCommand.Step, "RPC_Step" }, { RpcCommand.Wakeup, "RPC_Wakeup" }, { RpcCommand.Grow, "RPC_Grow" }, { RpcCommand.Shake, "RPC_Shake" }, { RpcCommand.Command, "RPC_Command" }, { RpcCommand.UnSummon, "RPC_UnSummon" }, { RpcCommand.SetName, "RPC_SetName" }, { RpcCommand.Forward, "RPC_Forward" }, { RpcCommand.Backward, "RPC_Backward" }, { RpcCommand.Rudder, "RPC_Rudder" }, { RpcCommand.Stop, "RPC_Stop" }, { RpcCommand.AddSaddle, "RPC_AddSaddle" }, { RpcCommand.RemoveSaddle, "RPC_RemoveSaddle" }, { RpcCommand.SetSaddle, "RPC_SetSaddle" }, { RpcCommand.RequestControlShip, "RPC_RequestControl" }, { RpcCommand.ReleaseControlShip, "RPC_ReleaseControl" }, { RpcCommand.SetGlobalKey, "RPC_SetGlobalKey" }, { RpcCommand.RemoveGlobalKey, "RPC_RemoveGlobalKey" }, { RpcCommand.GlobalKeys, "RPC_GlobalKeys" }, { RpcCommand.LocationIcons, "RPC_LocationIcons" }, { RpcCommand.AddNoise, "RPC_AddNoise" } }; } public static class Strings { public static string[] Effects => new string[146] { "AdrenalineRush", "AdrenalineRush2", "AdrenalineRush3", "AdrenalineRush4", "BeltStrength", "Burning", "CampFire", "Cold", "CorpseRun", "Demister", "Encumbered", "Freezing", "Frost", "GoblinShaman_shield", "GP_Bonemass", "GP_Eikthyr", "GP_Fader", "GP_Moder", "GP_Queen", "GP_TheElder", "GP_Yagluth", "Harpooned", "Immobilized", "ImmobilizedAshlands", "ImmobilizedLong", "Lightning", "Poison", "Potion_barleywine", "Potion_BugRepellent", "Potion_bzerker", "Potion_eitr_lingering", "Potion_eitr_minor", "Potion_frostresist", "Potion_hasty", "Potion_health_lingering", "Potion_health_major", "Potion_health_medium", "Potion_health_minor", "Potion_LightFoot", "Potion_poisonresist", "Potion_stamina_lingering", "Potion_stamina_medium", "Potion_stamina_minor", "Potion_strength", "Potion_swimmer", "Potion_tamer", "Potion_tasty", "Potion_TrollPheromones", "Puke", "Rested", "Resting", "SE_Dvergr_buff", "SE_Dvergr_heal", "SE_Greydwarf_shaman_heal", "SetEffect_AshlandsMediumArmor", "SetEffect_BerserkerArmor", "SetEffect_BerserkerUndeadArmor", "SetEffect_FenringArmor", "SetEffect_FishingHat", "SetEffect_HarvesterArmor", "SetEffect_MageArmor", "SetEffect_RootArmor", "SetEffect_TrollArmor", "SetEffect_WolfArmor", "Shelter", "Slimed", "SlowFall", "Smoked", "SoftDeath", "Spirit", "Staff_shield", "Tared", "TrinketBlackDamageHealth", "TrinketBlackStamina", "TrinketBronzeHealth", "TrinketBronzeStamina", "TrinketCarapaceEitr", "TrinketChitinSwim", "TrinketFlametalEitr", "TrinketFlametalStaminaHealth", "TrinketIronHealth", "TrinketIronStamina", "TrinketScaleStaminaDamage", "TrinketSilverDamage", "TrinketSilverResist", "Warm", "Wet", "WindRun", "Wishbone", "Potion__minor_stamina_lingering_TW", "Potion__medium_stamina_lingering_TW", "Potion_lightningresist_TW", "Effect_CapeRotten_TW", "SE_Decapitator5_TW", "SE_Vampirism_TW", "SE_Decapitator4_TW", "SE_Smasher_TW", "SE_Crusher_TW", "PinnedModer", "SE_Piercer_TW", "Piercing", "Warfare_LightningBurstStacking", "SE_Executioner_15_TW", "SE_Meteor_TW", "SE_Rip_TW", "SE_Bleeding_TW", "SE_Adrenaline_TW", "SE_Hunger_TW", "SE_Shredder_TW", "SE_Bash_3_TW", "SE_Bash_2_TW", "SE_Bash_4_TW", "SE_Bash_5_TW", "SE_Impale_TW", "PreventPulling", "Warfare_Adrenaline", "Warfare_Bleeding", "Warfare_Bleeding_Stacking", "Warfare_BleedingSecondaryAttack", "Warfare_Bludgeoner", "Warfare_Bludgeoner_ShreadResistance", "Warfare_BurningSecondaryAttack", "Warfare_Decapitator", "Warfare_Decapitator_ShreadResistance", "Warfare_EikthyrCrossbow", "Warfare_Ghost", "Warfare_HacknSlash", "Warfare_HacknSlash_ShreadResistance", "Warfare_Haste", "Warfare_Haste_Stacking", "Warfare_Impale", "Warfare_Juggernaut", "Warfare_Juggernaut_ShreadResistance", "Warfare_PiercingGreatbowMistlands", "Warfare_PiercingGreatbowPlains", "Warfare_Pinned", "Warfare_PinnedFrozen", "Warfare_Protector", "Warfare_Protector_Stacking", "Warfare_Shatter", "Warfare_Smasher", "Warfare_Smasher_ShreadResistance", "Warfare_SmashnBash", "Warfare_SmashnBash_ShreadResistance", "Warfare_Vampirism", "Paralyze" }; } public static class StringUtils { public static int GetStableHashCode(this string str) { int num = 5381; foreach (char c in str) { num = (num * 33) ^ c; } return num; } } } namespace PolyhydraGames.Valheim.Plugin.Commands { internal class GetEvent : RconCommand { public override string Command => "getevent"; public override string Description => "Get current active/random raid event."; protected override string OnHandle(CommandArgs args) { RandomEvent activeEvent = RandEventSystem.instance.GetActiveEvent(); RandomEvent currentRandomEvent = RandEventSystem.instance.GetCurrentRandomEvent(); if (activeEvent == null && currentRandomEvent == null) { return "No active raid."; } return "Active: " + (activeEvent?.m_name ?? "none") + " | Random: " + (currentRandomEvent?.m_name ?? "none"); } } internal class Impersonate : RconCommand { private static readonly Dictionary<string, UserInfo> ImpersonatedUsers = new Dictionary<string, UserInfo>(); private static ulong NextId = 1uL; public override string Command => "impersonate"; public override string Description => "Sends a message to the chat as a shout. Usage: impersonate <name> <message>"; public UserInfo CreateUser(string name) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown return new UserInfo { Name = name, UserId = new PlatformUserID("Bot", NextId++, false) }; } private UserInfo GetUserInfo(string name) { if (ImpersonatedUsers.ContainsKey(name)) { return ImpersonatedUsers[name]; } return CreateUser(name); } protected override string OnHandle(CommandArgs args) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (args.Arguments.Count < 2) { return "Usage: impersonate <name> <message>"; } string text = ""; string text2 = ""; try { text = args.GetString(0); text2 = string.Join(" ", args.Arguments.Skip(1)); Vector3 val = default(Vector3); if (!ZoneSystem.instance.GetLocationIcon(Game.instance.m_StartLocation, ref val)) { ((Vector3)(ref val))..ctor(0f, 30f, 0f); } ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ChatMessage", new object[4] { val, 2, GetUserInfo(text), text2 }); return "Impersonated: " + text + " - " + text2; } catch (Exception ex) { return ex.Message + " FAILED !!! Impersonated: " + text + " - " + text2; } } } internal class ListEvents : RconCommand { public override string Command => "listevents"; public override string Description => "List all available random events."; protected override string OnHandle(CommandArgs args) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Available events:"); foreach (RandomEvent @event in RandEventSystem.instance.m_events) { stringBuilder.AppendLine($"- {@event.m_name} (enabled={@event.m_enabled})"); } return stringBuilder.ToString(); } } public abstract class PolyRconCommand : RconCommand { public static readonly UserInfo ServerUserInfo = new UserInfo { Name = string.Empty, UserId = new PlatformUserID("Bot", 0uL, false) }; public abstract string Method { get; } protected override string OnHandle(CommandArgs args) { string @string = args.GetString(0); ZNetPeer val = ZNet.instance.GetPeerByHostName(@string) ?? ZNet.instance.GetPeerByPlayerName(@string); if (val == null) { return "Cannot find user " + @string; } ZDO zDO = PlayerUtils.GetZDO(val); return (zDO == null) ? ("Cannot handle command for player " + PlayerUtils.GetPlayerInfo(val) + ". ZDO not found") : OnHandle(PlayerWrapper.Create(val), args); } protected abstract string OnHandle(PlayerWrapperType player, CommandArgs args); protected void InvokeRouted(PlayerWrapperType player, params object[] items) { ZRoutedRpc.instance.InvokeRoutedRPC(player.ZDOID, Method, items); } } internal class RaidCommand : PolyRconCommand { public override string Command => "raid"; public override string Description => "Start a raid. Usage: raid <eventName> [player]"; public override string Method { get; } = ""; protected override string OnHandle(PlayerWrapperType player, CommandArgs args) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (args.Arguments.Count < 1) { return "Usage: raid [playerId] <eventName>"; } string @string = args.GetString(1); Vector3 refPosition = player.RefPosition; if (!RandEventSystem.instance.HaveEvent(@string)) { return "No such event: " + @string; } RandEventSystem.instance.SetRandomEventByName(@string, refPosition); return "Raid started: " + @string + " " + ((refPosition != Vector3.zero) ? "at player" : "globally"); } } internal class StartRandomRaid : RconCommand { public override string Command => "startraid"; public override string Description => "Start a random raid from eligible events."; protected override string OnHandle(CommandArgs args) { RandEventSystem.instance.ConsoleStartRandomEvent(); return "Random raid triggered."; } } internal class StopRaid : RconCommand { public override string Command => "stopraid"; public override string Description => "Stop the current raid/event."; protected override string OnHandle(CommandArgs args) { RandEventSystem.instance.ConsoleResetRandomEvent(); return "Raid/event stopped."; } } } namespace PolyhydraGames.Valheim.Plugin.Broke_Commands { internal class Explode : PolyRconCommand { public override string Command => "explode"; public override string Description => "Explode a player. Usage: explode <player>"; public override string Method { get; } = ""; protected override string OnHandle(PlayerWrapperType player, CommandArgs args) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (args.Arguments.Count < 1) { return "Usage: explode <player>"; } Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_explosion"), player.RefPosition, Quaternion.identity); return "Boom! Exploded " + player.Name + "."; } } internal class ResetWind : RconCommand { public override string Command => "resetwind"; public override string Description => "Reset wind to normal."; protected override string OnHandle(CommandArgs args) { EnvMan instance = EnvMan.instance; if (instance != null) { instance.ResetDebugWind(); } return "Wind reset."; } } internal class SetTime : RconCommand { public override string Command => "settime"; public override string Description => "Set time of day fraction (0=midnight, 0.5=noon)."; protected override string OnHandle(CommandArgs args) { if (args.Arguments.Count < 1) { return "Usage: settime <0.0-1.0>"; } if (!float.TryParse(args.GetString(0), out var result)) { return "Invalid number"; } EnvMan.instance.m_debugTimeOfDay = true; EnvMan.instance.m_debugTime = Mathf.Clamp01(result); return $"Time set to {result}"; } } internal class SetWeather : RconCommand { public override string Command => "setweather"; public override string Description => "Forces the environment/weather. Usage: setweather <name>"; private string Usage() { string text = string.Join(", ", Helpers.GetEnvironmentNames()); return "Usage: setweather <envName> (" + text + ")"; } protected override string OnHandle(CommandArgs args) { if ((Object)(object)EnvMan.instance == (Object)null) { return "EnvMan not initialized"; } if (args.Arguments.Count < 1) { return Usage(); } string envName = args.GetString(0); List<string> environmentNames = Helpers.GetEnvironmentNames(); if (environmentNames.All((string x) => x != envName)) { return Usage(); } EnvMan.instance.SetForceEnvironment(envName); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "RPC_SetEnvironment", new object[2] { envName, 0f }); return "Forced environment set to " + envName; } } internal class SetWind : RconCommand { public override string Command => "setwind"; public override string Description => "Set wind. Usage: setwind <angle> <intensity>"; protected override string OnHandle(CommandArgs args) { if (args.Arguments.Count < 2) { return "Usage: setwind <angle> <intensity>"; } if (!float.TryParse(args.GetString(0), out var result) || !float.TryParse(args.GetString(1), out var result2)) { return "Invalid numbers"; } EnvMan instance = EnvMan.instance; if (instance != null) { instance.SetDebugWind(result, result2); } ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "RPC_SetDebugWind", new object[2] { result, result2 }); return $"Wind forced: {result}°, {result2}"; } } internal class SkipMorning : RconCommand { public override string Command => "skipmorning"; public override string Description => "Skips to next morning."; protected override string OnHandle(CommandArgs args) { EnvMan instance = EnvMan.instance; if (instance != null) { instance.SkipToMorning(); } return "Skipped to morning."; } } internal class Stagger : PolyRconCommand { public override string Command => "stagger"; public override string Description => "stagger the player. Usage: stagger <player>"; public override string Method => RpcCommand.Stagger.GetRpcCommandName(); protected override string OnHandle(PlayerWrapperType player, CommandArgs args) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (args.Arguments.Count < 2) { return ((RconCommand)this).Description; } object[] array = new object[1]; Vector3 refPosition = player.RefPosition; refPosition.x = player.RefPosition.x + 1f; array[0] = refPosition; InvokeRouted(player, array); return "Staggered " + player.Name; } } } namespace PolyhydraGames.Valheim.Plugin.AddNoise { [HarmonyPatch(typeof(Game))] public static class AddNoiseBootStrap { [HarmonyPostfix] [HarmonyPatch("Start")] private static void Register() { Logger.LogInfo((object)"Registered AddNoiseBootStrap"); ZRoutedRpc.instance.Register<string, Vector3>("AddNoise", (Action<long, string, Vector3>)PlayNoise); } private static void PlayNoise(long sender, string effectName, Vector3 _) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) Vector3 position = Player.m_localPlayer.GetPosition(); if (effectName.Contains("https:")) { Logger.LogInfo((object)("Received URL request to playNoise " + effectName)); try { AudioHelper audioHelper = new AudioHelper(); ((MonoBehaviour)CoroutineRunner.Instance).StartCoroutine(audioHelper.PlayAudioFromUrl(effectName, position)); return; } catch (Exception ex) { Logger.LogError((object)ex.Message); return; } } Logger.LogInfo((object)("Received URL request to playNoise " + effectName)); GameObject prefab = PrefabManager.Instance.GetPrefab(effectName); if ((Object)(object)prefab != (Object)null) { Object.Instantiate<GameObject>(prefab, position, Quaternion.identity); Logger.LogWarning((object)$"Played {effectName} at {position}"); } else { Logger.LogWarning((object)("Effect prefab " + effectName + " not found!")); } } } internal class AddNoise : PolyRconCommand { public override string Command => "addnoise"; public override string Description => "Plays a noise in the vicinity of the player."; public override string Method => "AddNoise"; protected override string OnHandle(PlayerWrapperType player, CommandArgs args) { //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_0047: Unknown result type (might be due to invalid IL or missing references) if (args.Arguments.Count < 2) { return "Usage: addnoise <player> <noiseName> <position>"; } string @string = args.GetString(1); Vector3 vector = CommandArgsExtensions.GetVector3(args, 2); ZRoutedRpc.instance.InvokeRoutedRPC(player.ZDOID, "AddNoise", new object[2] { @string, vector }); return "Played noise '" + @string + "' at " + player.Name; } } public static class Metadata { public const string TestString = "addnoise 76561197962914477 https://cdn.polyhydragames.com/audio/no.mp3 10 10 1"; public const string RCPCall = "AddNoise"; public const string Command = "addnoise"; public const string Description = "Plays a noise in the vicinity of the player."; public const string Usage = "Usage: addnoise <player> <noiseName> <position>"; public const int MinimumParameters = 2; } } namespace PolyhydraGames.Valheim.Plugin.AddEffect { [HarmonyPatch(typeof(Game))] public static class AddEffectBootStrap { [HarmonyPostfix] [HarmonyPatch("Start")] public static void Register() { Logger.LogInfo((object)"Registered AddEffectBootStrap"); ZRoutedRpc.instance.Register<string>("ApplyStatusEffect", (Action<long, string>)OnApplyStatusEffect); } private static void OnApplyStatusEffect(long sender, string effectName) { Logger.LogInfo((object)("Client received request to apply " + effectName)); Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { StatusEffect effect = Helpers.GetEffect(effectName); if ((Object)(object)effect != (Object)null) { ((Character)localPlayer).GetSEMan().AddStatusEffect(effect, true, 0, 0f); ((Terminal)Chat.instance).AddString("[Odin] You are blessed with " + effect.m_name + "!"); } else { Logger.LogWarning((object)("StatusEffect " + effectName + " not found in ObjectDB")); } } } } internal class AddEffect : PolyRconCommand { public override string Command => "addeffect"; public override string Description => "Adds a status to the player. Usage: addstatus <player> <statusName>"; public override string Method => "ApplyStatusEffect"; private string ProcessCommand(PlayerWrapperType player, CommandArgs args) { string @string = args.GetString(1); InvokeRouted(player, @string); return "Applied status '" + @string + "' to " + player.Name; } protected override string OnHandle(PlayerWrapperType player, CommandArgs args) { if (args.Arguments.Count < 2) { return "Usage: addstatus <player> <statusName>"; } return ProcessCommand(player, args); } } public static class Metadata { public const string Test = "addeffect 76561197962914477 SE_Rested"; public const string RCPCall = "ApplyStatusEffect"; public const string Command = "addeffect"; public const string Description = "Adds a status to the player. Usage: addstatus <player> <statusName>"; public const string Usage = "Usage: addstatus <player> <statusName>"; public const int MinimumParameters = 2; } }