Please disclose if any significant portion of your mod was created 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 EmeraudeAdmin v1.3.0
plugins/EmeraudeAdmin.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("EmeraudeAdmin")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.3.0.0")] [assembly: AssemblyInformationalVersion("1.3.0+73ed6ca8c6254f5ea1772e8735f31dfbfd8a640b")] [assembly: AssemblyProduct("EmeraudeAdmin")] [assembly: AssemblyTitle("EmeraudeAdmin")] [assembly: AssemblyVersion("1.3.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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; } } } namespace EmeraudeAdmin { internal static class Client { private const float CheckEvery = 1f; private static Player tracked; private static Dictionary<string, int> last; private static string lastSnapshot; private static float nextCheck; private static float nextSnapshot; private static float SnapshotEvery => (float)Plugin.SnapshotEveryMinutes.Value * 60f; private static string Key(ItemData item) { string text = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : item.m_shared.m_name); if (item.m_quality <= 1) { return text; } return $"{text}*{item.m_quality}"; } private static Dictionary<string, int> Count(Player p) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); foreach (ItemData allItem in ((Humanoid)p).GetInventory().GetAllItems()) { string key = Key(allItem); dictionary.TryGetValue(key, out var value); dictionary[key] = value + allItem.m_stack; } return dictionary; } private static void Send(string kind, Player p, string data) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) ZRoutedRpc.instance.InvokeRoutedRPC("EA_Log", new object[3] { kind, ((Component)p).transform.position, data }); } public static void Tick() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { tracked = null; } else { if (Time.time < nextCheck) { return; } nextCheck = Time.time + 1f; Dictionary<string, int> dictionary = Count(localPlayer); if ((Object)(object)localPlayer != (Object)(object)tracked) { tracked = localPlayer; last = dictionary; lastSnapshot = Net.Encode(dictionary); nextSnapshot = Time.time + SnapshotEvery; Send("apparition", localPlayer, lastSnapshot); return; } Dictionary<string, int> dictionary2 = new Dictionary<string, int>(); foreach (string item in dictionary.Keys.Union(last.Keys)) { dictionary.TryGetValue(item, out var value); last.TryGetValue(item, out var value2); if (value != value2) { dictionary2[item] = value - value2; } } if (dictionary2.Count > 0) { Send("delta", localPlayer, Net.Encode(dictionary2)); } last = dictionary; if (Time.time >= nextSnapshot) { nextSnapshot = Time.time + SnapshotEvery; string text = Net.Encode(dictionary); if (text != lastSnapshot) { Send("inventaire", localPlayer, text); } lastSnapshot = text; } } } public static void OnSaved(Player p) { if (ZRoutedRpc.instance != null && !((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsDedicated()) { lastSnapshot = Net.Encode(last = Count(p)); Send("sauvegarde", p, lastSnapshot); } } public static void OnDeath(Player p) { if (ZRoutedRpc.instance != null) { Send("mort", p, Net.Encode(Count(p))); } } public static void OnReply(long sender, string text) { if (Net.FromServer(sender)) { Console instance = Console.instance; if (instance != null) { instance.Print("[Emeraude Admin] " + text); } } } public static void OnTeleport(long sender, Vector3 pos, bool exact) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (Net.FromServer(sender) && !((Object)(object)localPlayer == (Object)null)) { ((Character)localPlayer).TeleportTo(pos, ((Component)localPlayer).transform.rotation, true); } } public static void OnGive(long sender, string prefab, int amount, int quality) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Net.FromServer(sender) || (Object)(object)localPlayer == (Object)null) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { return; } int num = Math.Max(1, val.m_itemData.m_shared.m_maxStackSize); Inventory inventory = ((Humanoid)localPlayer).GetInventory(); for (int num2 = amount; num2 > 0; num2 -= num) { int num3 = Math.Min(num2, num); if (inventory.AddItem(prefab, num3, quality, 0, 0L, "", false, false) == null) { ItemData obj = val.m_itemData.Clone(); obj.m_quality = quality; obj.m_dropPrefab = itemPrefab; ItemDrop.DropItem(obj, num3, ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward + Vector3.up, Quaternion.identity); } } ((Character)localPlayer).Message((MessageType)2, L.T($"Received: {amount} {prefab}", $"Reçu : {amount} {prefab}"), 0, (Sprite)null, false); } } internal static class Commands { public const string Prefix = "adm:"; public static readonly (string name, string alias, string usageEn, string usageFr)[] All = new(string, string, string, string)[6] { ("players", "joueurs", "lists the players in game and their positions", "liste les joueurs en jeu et leur position"), ("pos", null, "<player> : position of a player", "<joueur> : position d'un joueur"), ("inv", null, "<player> : inventory of a player (as known by the server)", "<joueur> : inventaire d'un joueur (connu du serveur)"), ("tp", null, "<player> <player> or <player> <x> <z> : teleports a player", "<joueur> <joueur> ou <joueur> <x> <z> : téléporte un joueur"), ("give", null, "<player> <item> [amount] [quality] : gives an item (English prefab name)", "<joueur> <objet> [quantité] [qualité] : donne un objet (nom anglais du prefab)"), ("help", "aide", ": lists the commands", ": liste des commandes") }; public static string Help => L.T("Admin commands:", "Commandes admin :") + "\n" + string.Join("\n", All.Select(delegate((string name, string alias, string usageEn, string usageFr) c) { string text; if (!L.Fr || c.alias == null) { (text, _, _, _) = c; } else { text = c.alias; } return " adm:" + text + " " + L.T(c.usageEn, c.usageFr); })); public static string Canonical(string cmd) { return All.FirstOrDefault(((string name, string alias, string usageEn, string usageFr) c) => c.name == cmd || c.alias == cmd).name ?? cmd; } public static void Register() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) (string, string, string, string)[] all = All; for (int i = 0; i < all.Length; i++) { (string name, string alias, string usageEn, string usageFr) c = all[i]; ConsoleEvent val = (ConsoleEvent)delegate(ConsoleEventArgs args) { if (ZRoutedRpc.instance == null || (Object)(object)ZNet.instance == (Object)null) { Terminal context = args.Context; if (context != null) { context.AddString(L.T("Connect to the server first.", "Connecte-toi d'abord au serveur.")); } } else { string text2 = c.name + ((args.Args.Length > 1) ? (" " + string.Join(" ", args.Args.Skip(1))) : ""); ZRoutedRpc.instance.InvokeRoutedRPC("EA_Admin", new object[1] { text2 }); } }; string text = L.T(c.usageEn, c.usageFr) + " (admins, Emeraude Admin)"; new ConsoleCommand("adm:" + c.name, text, val, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); if (c.alias != null) { new ConsoleCommand("adm:" + c.alias, text, val, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } } } public enum Language { English, French } internal static class L { public static bool Fr { get { if (Plugin.Lang != null) { return Plugin.Lang.Value == Language.French; } return false; } } public static string T(string en, string fr) { if (!Fr) { return en; } return fr; } } internal static class Net { public const string Log = "EA_Log"; public const string Admin = "EA_Admin"; public const string Reply = "EA_Reply"; public const string Teleport = "EA_Teleport"; public const string Give = "EA_Give"; public static void Register() { ZRoutedRpc instance = ZRoutedRpc.instance; instance.Register<string, Vector3, string>("EA_Log", (Action<long, string, Vector3, string>)Server.OnLog); instance.Register<string>("EA_Admin", (Action<long, string>)Server.OnAdmin); instance.Register<string>("EA_Reply", (Action<long, string>)Client.OnReply); instance.Register<Vector3, bool>("EA_Teleport", (Action<long, Vector3, bool>)Client.OnTeleport); instance.Register<string, int, int>("EA_Give", (Action<long, string, int, int>)Client.OnGive); } public static bool FromServer(long sender) { if (ZNet.instance.IsServer()) { return sender == ZNet.GetUID(); } ZNetPeer serverPeer = ZNet.instance.GetServerPeer(); if (serverPeer != null) { return serverPeer.m_uid == sender; } return false; } public static string Encode(Dictionary<string, int> items) { return string.Join(";", from kv in items where kv.Value != 0 select kv.Key + ":" + kv.Value); } public static Dictionary<string, int> Decode(string text) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); string[] array = (text ?? "").Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text2 in array) { int num = text2.LastIndexOf(':'); if (num > 0 && int.TryParse(text2.Substring(num + 1), out var result)) { dictionary[text2.Substring(0, num)] = result; } } return dictionary; } public static string Pos(Vector3 p) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return $"({p.x:0}, {p.y:0}, {p.z:0})"; } } [HarmonyPatch(typeof(Game), "Start")] internal static class GameStartPatch { private static void Postfix() { Net.Register(); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class TerminalPatch { private static void Postfix() { Commands.Register(); } } [HarmonyPatch(typeof(ZNet), "Disconnect")] internal static class DisconnectPatch { private static void Prefix(ZNetPeer peer) { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { Server.OnDisconnect(peer); } } } [HarmonyPatch(typeof(Game), "SavePlayerProfile")] internal static class SaveProfilePatch { private static void Postfix(Game __instance) { if (__instance.m_saveTimer == 0f && (Object)(object)Player.m_localPlayer != (Object)null) { Client.OnSaved(Player.m_localPlayer); } } } [HarmonyPatch(typeof(Player), "OnDeath")] internal static class DeathPatch { private static void Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { Client.OnDeath(__instance); } } } [BepInPlugin("emeraude.admin", "Emeraude Admin", "1.3.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "emeraude.admin"; public const string Name = "Emeraude Admin"; public const string Version = "1.3.0"; internal static ConfigEntry<Language> Lang; internal static ConfigEntry<int> PositionEverySeconds; internal static ConfigEntry<int> SnapshotEveryMinutes; internal static ConfigEntry<int> KeptSaves; private void Awake() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) Lang = ((BaseUnityPlugin)this).Config.Bind<Language>("General", "Language", Language.English, "Language of the in-game messages, of the replies to admins and of the journal (server side). / Langue des messages en jeu, des réponses aux admins et du journal (côté serveur)."); PositionEverySeconds = ((BaseUnityPlugin)this).Config.Bind<int>("Journal", "PositionEverySeconds", 60, new ConfigDescription("Server: interval between two logged positions for each player, in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 3600), Array.Empty<object>())); SnapshotEveryMinutes = ((BaseUnityPlugin)this).Config.Bind<int>("Journal", "SnapshotEveryMinutes", 5, new ConfigDescription("Player: interval between two full inventories sent to the server (only if it changed), in minutes.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>())); KeptSaves = ((BaseUnityPlugin)this).Config.Bind<int>("Journal", "KeptSaves", 3, new ConfigDescription("Server: number of archived save periods kept per player (<player>.1.log, .2.log…).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); new Harmony("emeraude.admin").PatchAll(typeof(Plugin).Assembly); if (Traverse.Create(typeof(Terminal)).Field<bool>("m_terminalInitialized").Value) { Commands.Register(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded ({2})", "Emeraude Admin", "1.3.0", Lang.Value)); } private void Update() { if (!((Object)(object)ZNet.instance == (Object)null) && ZRoutedRpc.instance != null) { if (ZNet.instance.IsServer()) { Server.Tick(); } Client.Tick(); } } } internal static class Server { private static readonly Encoding Utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); private static readonly HashSet<long> online = new HashSet<long>(); private static readonly Dictionary<long, Dictionary<string, int>> inventories = new Dictionary<long, Dictionary<string, int>>(); private static float nextPosition; private static string dir; private static string Dir { get { if (dir == null) { dir = Path.Combine(Paths.ConfigPath, "journal"); Directory.CreateDirectory(dir); } return dir; } } private static string SteamId(ZNetPeer peer) { object obj; if (peer == null) { obj = null; } else { ISocket socket = peer.m_socket; obj = ((socket != null) ? socket.GetHostName() : null); } if (obj == null) { obj = "hote"; } return (string)obj; } private static string Clean(string s) { return new string((s ?? "").Select((char c) => (!char.IsLetterOrDigit(c) && c != '-' && c != '_') ? '_' : c).ToArray()); } private static string FileOf(ZNetPeer peer, string name) { return Clean(name) + "_" + Clean(SteamId(peer)); } private static void Write(string file, string line) { try { File.AppendAllText(Path.Combine(Dir, file), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " | " + line + "\n", Utf8); } catch (Exception ex) { Debug.LogWarning((object)("[Emeraude Admin] cannot write the journal: " + ex.Message)); } } private static void Journal(ZNetPeer peer, string name, Vector3 pos, string text) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Write(FileOf(peer, name) + ".log", Net.Pos(pos) + " | " + text); } private static void Rotate(string file) { try { int value = Plugin.KeptSaves.Value; File.Delete(PathOf(value)); for (int num = value - 1; num >= 0; num--) { if (File.Exists(PathOf(num))) { File.Move(PathOf(num), PathOf(num + 1)); } } } catch (Exception ex) { Debug.LogWarning((object)("[Emeraude Admin] cannot archive the journal: " + ex.Message)); } string PathOf(int i) { return Path.Combine(Dir, (i == 0) ? (file + ".log") : $"{file}.{i}.log"); } } private static string Describe(Dictionary<string, int> inv) { if (inv.Count != 0) { return string.Join(", ", from kv in inv orderby kv.Key select $"{kv.Key} ×{kv.Value}"); } return L.T("empty", "vide"); } private static string DescribeDelta(Dictionary<string, int> delta) { return string.Join(", ", from kv in delta orderby kv.Key select ((kv.Value > 0) ? "+" : "") + kv.Value + " " + kv.Key); } private static IEnumerable<ZNetPeer> InGame() { return from p in ZNet.instance.GetPeers() where p.IsReady() && !((ZDOID)(ref p.m_characterID)).IsNone() && !string.IsNullOrEmpty(p.m_playerName) select p; } public static void Tick() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) foreach (ZNetPeer item in InGame()) { if (online.Add(item.m_uid)) { Journal(item, item.m_playerName, item.m_refPos, L.T("connected", "connexion")); } } if (Time.time < nextPosition) { return; } nextPosition = Time.time + (float)Plugin.PositionEverySeconds.Value; foreach (ZNetPeer item2 in InGame()) { Journal(item2, item2.m_playerName, item2.m_refPos, L.T("position", "position")); } } public static void OnDisconnect(ZNetPeer peer) { //IL_001e: 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) if (peer != null && online.Remove(peer.m_uid)) { Journal(peer, peer.m_playerName, peer.m_refPos, L.T("disconnected", "déconnexion")); if (inventories.TryGetValue(peer.m_uid, out var value)) { Journal(peer, peer.m_playerName, peer.m_refPos, L.T("inventory when leaving: ", "inventaire au départ : ") + Describe(value)); } inventories.Remove(peer.m_uid); } } public static void OnLog(long sender, string kind, Vector3 pos, string data) { //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if (!ZNet.instance.IsServer()) { return; } ZNetPeer peer = ZNet.instance.GetPeer(sender); object obj = peer?.m_playerName; if (obj == null) { Game instance = Game.instance; if (instance == null) { obj = null; } else { PlayerProfile playerProfile = instance.GetPlayerProfile(); obj = ((playerProfile != null) ? playerProfile.GetName() : null); } if (obj == null) { obj = "?"; } } string name = (string)obj; Dictionary<string, int> dictionary = Net.Decode(data); if (!inventories.TryGetValue(sender, out var value)) { value = (inventories[sender] = new Dictionary<string, int>()); } switch (kind) { case "delta": foreach (KeyValuePair<string, int> item in dictionary) { value.TryGetValue(item.Key, out var value2); if (value2 + item.Value == 0) { value.Remove(item.Key); } else { value[item.Key] = value2 + item.Value; } } Journal(peer, name, pos, DescribeDelta(dictionary)); break; case "sauvegarde": inventories[sender] = dictionary; Journal(peer, name, pos, L.T("character saved, inventory: ", "personnage sauvegardé, inventaire : ") + Describe(dictionary)); Rotate(FileOf(peer, name)); break; case "mort": Journal(peer, name, pos, L.T("DIED, inventory left in the tombstone: ", "MORT, inventaire laissé dans la tombe : ") + Describe(dictionary)); break; default: { inventories[sender] = dictionary; string text = ((kind == "apparition") ? L.T("spawned with", "apparition") : L.T("inventory", "inventaire")); Journal(peer, name, pos, text + L.T(": ", " : ") + Describe(dictionary)); break; } } } private static void Reply(long to, string text) { ZRoutedRpc.instance.InvokeRoutedRPC(to, "EA_Reply", new object[1] { text }); } private static ZNetPeer Find(string name, out string error) { List<ZNetPeer> source = InGame().ToList(); List<ZNetPeer> list = source.Where((ZNetPeer p) => p.m_playerName.Equals(name, StringComparison.OrdinalIgnoreCase)).ToList(); List<ZNetPeer> list2 = ((list.Count > 0) ? list : source.Where((ZNetPeer p) => p.m_playerName.StartsWith(name, StringComparison.OrdinalIgnoreCase)).ToList()); error = ((list2.Count == 1) ? null : ((list2.Count == 0) ? (L.T("Player \"" + name + "\" not found. Online: ", "Joueur « " + name + " » introuvable. En ligne : ") + string.Join(", ", source.Select((ZNetPeer p) => p.m_playerName))) : (L.T("\"" + name + "\" is ambiguous: ", "« " + name + " » est ambigu : ") + string.Join(", ", list2.Select((ZNetPeer p) => p.m_playerName))))); if (list2.Count != 1) { return null; } return list2[0]; } private static GameObject FindItem(string name) { return ((IEnumerable<GameObject>)ObjectDB.instance?.m_items).FirstOrDefault((Func<GameObject, bool>)((GameObject i) => (Object)(object)i != (Object)null && ((Object)i).name.Equals(name, StringComparison.OrdinalIgnoreCase) && (Object)(object)i.GetComponent<ItemDrop>() != (Object)null)); } public static void OnAdmin(long sender, string line) { if (ZNet.instance.IsServer()) { ZNetPeer peer = ZNet.instance.GetPeer(sender); bool num = sender == ZNet.GetUID(); string text = (num ? "hôte" : (peer?.m_playerName ?? sender.ToString())); if (!num && (peer == null || !ZNet.instance.IsAdmin(SteamId(peer)))) { Write("admin.log", L.T("REFUSED ", "REFUSÉ ") + text + " (" + SteamId(peer) + ") : " + line); Reply(sender, L.T("You are not an admin of this server (adminlist.txt).", "Tu n'es pas admin du serveur (adminlist.txt).")); } else { Write("admin.log", text + " : " + line); Reply(sender, Run(line.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries), text)); } } } private static string Run(string[] a, string admin) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) string error; switch (Commands.Canonical((a.Length != 0) ? a[0] : "")) { case "players": { List<ZNetPeer> list = InGame().ToList(); if (list.Count != 0) { return string.Join("\n", list.Select((ZNetPeer p) => p.m_playerName + " " + Net.Pos(p.m_refPos))); } return L.T("Nobody in game.", "Personne en jeu."); } case "pos": { if (a.Length < 2) { return L.T("Usage: adm:pos <player>", "Usage : adm:pos <joueur>"); } ZNetPeer val4 = Find(a[1], out error); if (val4 != null) { return val4.m_playerName + L.T(" is at ", " est en ") + Net.Pos(val4.m_refPos); } return error; } case "inv": { if (a.Length < 2) { return L.T("Usage: adm:inv <player>", "Usage : adm:inv <joueur>"); } ZNetPeer val3 = Find(a[1], out error); if (val3 == null) { return error; } if (!inventories.TryGetValue(val3.m_uid, out var value)) { return val3.m_playerName + L.T(": inventory unknown (Emeraude Admin not installed on their game?)", " : inventaire inconnu (Emeraude Admin absent chez lui ?)"); } return val3.m_playerName + L.T(": ", " : ") + Describe(value); } case "tp": { if (a.Length != 3 && a.Length != 4) { return L.T("Usage: adm:tp <player> <player> or adm:tp <player> <x> <z>", "Usage : adm:tp <joueur> <joueur> ou adm:tp <joueur> <x> <z>"); } ZNetPeer val5 = Find(a[1], out error); if (val5 == null) { return error; } Vector3 val6 = default(Vector3); bool flag; string text; if (a.Length == 4) { if (!float.TryParse(a[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3) || !float.TryParse(a[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result4)) { return L.T("Invalid coordinates: adm:tp <player> <x> <z>", "Coordonnées invalides : adm:tp <joueur> <x> <z>"); } ((Vector3)(ref val6))..ctor(result3, 30f, result4); flag = false; text = $"({result3:0}, {result4:0})"; } else { ZNetPeer val7 = Find(a[2], out error); if (val7 == null) { return error; } val6 = val7.m_refPos + new Vector3(1.5f, 0.5f, 0f); flag = true; text = val7.m_playerName + " " + Net.Pos(val7.m_refPos); } ZRoutedRpc.instance.InvokeRoutedRPC(val5.m_uid, "EA_Teleport", new object[2] { val6, flag }); Journal(val5, val5.m_playerName, val5.m_refPos, L.T("teleported by " + admin + " to " + text, "téléporté par " + admin + " vers " + text)); return val5.m_playerName + L.T(" teleported to " + text + ".", " téléporté vers " + text + "."); } case "give": { if (a.Length < 3) { return L.T("Usage: adm:give <player> <item> [amount] [quality]", "Usage : adm:give <joueur> <objet> [quantité] [qualité]"); } ZNetPeer val = Find(a[1], out error); if (val == null) { return error; } GameObject val2 = FindItem(a[2]); if ((Object)(object)val2 == (Object)null) { return L.T("Unknown item \"" + a[2] + "\" (English prefab name, e.g. Copper, Tin, Bronze, Wood).", "Objet « " + a[2] + " » inconnu (nom anglais du prefab, ex. Copper, Tin, Bronze, Wood)."); } int result = 1; int result2 = 1; if (a.Length > 3 && (!int.TryParse(a[3], out result) || result < 1 || result > 9999)) { return L.T("Invalid amount (1 to 9999).", "Quantité invalide (1 à 9999)."); } if (a.Length > 4 && (!int.TryParse(a[4], out result2) || result2 < 1 || result2 > 10)) { return L.T("Invalid quality (1 to 10).", "Qualité invalide (1 à 10)."); } ZRoutedRpc.instance.InvokeRoutedRPC(val.m_uid, "EA_Give", new object[3] { ((Object)val2).name, result, result2 }); Journal(val, val.m_playerName, val.m_refPos, L.T($"receives from {admin}: {result} {((Object)val2).name}", $"reçoit de {admin} : {result} {((Object)val2).name}") + ((result2 > 1) ? L.T($" (quality {result2})", $" (qualité {result2})") : "")); return L.T($"{result} {((Object)val2).name} given to {val.m_playerName}.", $"{result} {((Object)val2).name} donné(s) à {val.m_playerName}."); } default: return Commands.Help; } } } }