Иконка ресурса

FREE SoundLibraryApi : 1.1.0 1.1.0

Нет прав для скачивания
C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using Network;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using ProtoBuf;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("Sound Library Api", "supreme", "1.1.0")]
    [Description("Api for storing / playing player recorded sounds")]
    public class SoundLibraryApi : RustPlugin {
#region Class Fields
        [PluginReference]
        private Plugin HumanNpc, ZoneManager;
        private static SoundLibraryApi _pluginInstance;
        private PluginConfig _pluginConfig;
        private PluginData _pluginData;
        private readonly Hash<ulong, PlayerSpeaker> _playerSpeakers = new Hash<ulong, PlayerSpeaker>();
        private readonly Hash<uint, PlayerSpeaker> _botSpeakers = new Hash<uint, PlayerSpeaker>();
        private ItemDefinition _balaclava;
        private ItemDefinition _hoodie;
        private ItemDefinition _pants;
        private ItemDefinition _gloves;
        private ItemDefinition _boots;
        private const string UsePermission = "soundlibraryapi.use";
        private const string AudioMessagesPermission = "soundlibraryapi.audio";
        private const string SpeakerPrefab = "assets/prefabs/player/player.prefab";
        private enum HookActionType : byte {
            OnUseNPC = 0, OnEnterNPC = 1, OnLeaveNPC = 2, OnHitNPC = 3
        }
        private enum ZoneHookType : byte {
            OnEnterZone = 0, OnExitZone = 1
        }
#endregion
#region Hooks
        private void Init() {
            _pluginInstance = this;
        }
        private void OnServerInitialized() {
            LoadData();
            permission.RegisterPermission(UsePermission, this);
            permission.RegisterPermission(AudioMessagesPermission, this);
            _balaclava = ItemManager.FindItemDefinition("mask.balaclava");
            _hoodie = ItemManager.FindItemDefinition("hoodie");
            _pants = ItemManager.FindItemDefinition("pants");
            _gloves = ItemManager.FindItemDefinition("burlap.gloves");
            _boots = ItemManager.FindItemDefinition("shoes.boots");
            cmd.AddConsoleCommand("audio.message", this, nameof(ConsoleAudioCommand));
            if (_pluginConfig.ScheduledMessageInterval == 0f) {
                return;
            }
            timer.Every(_pluginConfig.ScheduledMessageInterval, () => {
                SendSoundToAll(_pluginConfig.ScheduledMessageFile.GetRandom());
            }
            );
        }
        private void Unload() {
            SaveData();
            foreach (PlayerSpeaker speaker in _playerSpeakers.Values.ToList()) {
                speaker.Destroy();
            }
            _pluginInstance = null;
        }
        // There's an issue where the npc speaker can pick up the player's voice data while talking
        private object OnPlayerVoice(BasePlayer player, byte[] data) {
            {
                NetWrite write = Net.sv.StartWrite();
                write.PacketID(Message.Type.VoiceData);
                write.UInt32(player.net.ID);
                write.BytesWithSize(data);
                NetWrite netWrite = write;
                SendInfo sendInfo = new SendInfo(BaseNetworkable.GetConnectionsWithin(player.transform.position, 100f).Where(c => c.userid != player.userID).ToList()) {
                    priority = Priority.Immediate
                }
                ;
                netWrite.Send(sendInfo);
            }
            if (player.activeTelephone) {
                player.activeTelephone.OnReceivedVoiceFromUser(data);
            }
            return true;
        }
        private void OnPlayerDisconnected(BasePlayer player, string reason) {
            _playerSpeakers[player.userID]?.Destroy();
        }
        //TODO: Remove CanNetwork hook and implement a limitedNetworking & SendAsSnapshot eventually
        private object CanNetworkTo(BasePlayer speaker, BasePlayer target) {
            if (_botSpeakers.ContainsKey(speaker.net.ID)) {
                if (!_playerSpeakers.ContainsKey(target.userID)) {
                    return false;
                }
            }
            return null;
        }
        private object OnEntityTakeDamage(BasePlayer player, HitInfo info) {
            if (_botSpeakers.ContainsKey(player.net.ID)) {
                return true;
            }
            return null;
        }
        private void OnPlayerCorpseSpawned(BasePlayer player, NPCPlayerCorpse corpse) {
            if (!_botSpeakers.ContainsKey(player.net.ID)) {
                return;
            }
            foreach (ItemContainer container in corpse.containers) {
                container.Clear();
            }
            corpse.containers = null;
            ItemManager.DoRemoves();
            NextTick(() => {
                corpse.Kill();
            }
            );
        }
        private void OnPlayerConnected(BasePlayer player) {
            if (!player) {
                return;
            }
            if (_pluginConfig.WelcomeMessage) {
                timer.Once(5f, () => {
                    SendSoundToPlayer(player.userID, _pluginConfig.WelcomeMessageFile.GetRandom());
                }
                );
            }
        }
        private void OnEntitySpawned(BaseHelicopter helicopter) {
            if (_pluginConfig.ChopperMessage) {
                SendSoundToAll(_pluginConfig.ChopperMessageFile.GetRandom());
            }
        }
        private void OnEntitySpawned(CargoShip ship) {
            if (_pluginConfig.CargoshipMessage) {
                SendSoundToAll(_pluginConfig.CargoshipMessageFile.GetRandom());
            }
        }
        private void OnEntitySpawned(CargoPlane plane) {
            if (_pluginConfig.AirdropMessage) {
                SendSoundToAll(_pluginConfig.AirdropMessageFile.GetRandom());
            }
        }
        private void OnEntitySpawned(CH47HelicopterAIController ch47) {
            if (_pluginConfig.ChinookMessage) {
                SendSoundToAll(_pluginConfig.ChinookMessageFile.GetRandom());
            }
        }
        private void OnCrateHack(HackableLockedCrate crate) {
            if (_pluginConfig.CrateHackMessage) {
                SendSoundToAll(_pluginConfig.CrateHackMessageFile.GetRandom());
            }
        }
#endregion
#region HumanNPC Hooks
        private void OnUseNPC(BasePlayer npc, BasePlayer player) {
            if (player.userID.IsSteamId()) {
                SendSoundToPlayer(player.userID, _pluginData.NpcsData[npc.userID]?.Filenames[HookActionType.OnUseNPC]?.GetRandom());
            }
        }
        private void OnEnterNPC(BasePlayer npc, BasePlayer player) {
            if (player.userID.IsSteamId()) {
                SendSoundToPlayer(player.userID, _pluginData.NpcsData[npc.userID]?.Filenames[HookActionType.OnEnterNPC]?.GetRandom());
            }
        }
        private void OnLeaveNPC(BasePlayer npc, BasePlayer player) {
            if (player.userID.IsSteamId()) {
                SendSoundToPlayer(player.userID, _pluginData.NpcsData[npc.userID]?.Filenames[HookActionType.OnLeaveNPC]?.GetRandom());
            }
        }
        private void OnHitNPC(BasePlayer npc, HitInfo info) {
            BasePlayer player = info.InitiatorPlayer;
            if (player && !player.IsNpc && player.userID.IsSteamId()) {
                SendSoundToPlayer(info.InitiatorPlayer.userID, _pluginData.NpcsData[npc.userID]?.Filenames[HookActionType.OnHitNPC]?.GetRandom());
            }
        }
#endregion
#region Zone Manager Hooks
        private void OnEnterZone(string zoneId, BasePlayer player) {
            SendSoundToPlayer(player.userID, _pluginData.ZonesData[zoneId]?.Filenames[ZoneHookType.OnEnterZone]?.GetRandom());
        }
        private void OnExitZone(string zoneId, BasePlayer player) {
            SendSoundToPlayer(player.userID, _pluginData.ZonesData[zoneId]?.Filenames[ZoneHookType.OnExitZone]?.GetRandom());
        }
#endregion
#region Audio Speaker
        private class PlayerSpeaker {
            private BasePlayer Target {
                get;
            }
            private BasePlayer Speaker {
                get;
                set;
            }
            private readonly List<SoundDataV2> _queuedSoundsV2 = new List<SoundDataV2>();
            private Coroutine QueuedRoutine {
                get;
                set;
            }
            private uint NetId {
                get;
                set;
            }
            private long StartTime {
                get;
                set;
            }
            private long LastTick {
                get;
                set;
            }
            public PlayerSpeaker(BasePlayer target) {
                Target = target;
                CreateSpeaker(target);
            }
            private void CreateSpeaker(BasePlayer target) {
                Speaker = (BasePlayer) GameManager.server.CreateEntity(SpeakerPrefab, Vector3.down * 5 + Vector3.back * _pluginInstance._pluginConfig.SpeakerDistance);
                Speaker.Spawn();
                Speaker.RemovePlayerRigidbody();
                Speaker.DisablePlayerCollider();
                Speaker.SetParent(target);
                NetId = Speaker.net.ID;
                Speaker.inventory.containerMain.Clear();
                Speaker.inventory.containerBelt.Clear();
                Speaker.inventory.containerWear.Clear();
                ItemManager.DoRemoves();
                _pluginInstance.NextTick(() => {
                    Speaker.inventory.containerWear.AddItem(_pluginInstance._balaclava, 1, 1110601275);
                    Speaker.inventory.containerWear.AddItem(_pluginInstance._hoodie, 1, 883710255);
                    Speaker.inventory.containerWear.AddItem(_pluginInstance._pants, 1, 883709785);
                    Speaker.inventory.containerWear.AddItem(_pluginInstance._gloves, 1, 883710591);
                    Speaker.inventory.containerWear.AddItem(_pluginInstance._boots, 1, 883709405);
                }
                );
                _pluginInstance._botSpeakers[NetId] = this;
            }
            public void QueueSoundV2(SoundDataV2 data) {
                _queuedSoundsV2.Add(data);
                if (QueuedRoutine == null) {
                    QueuedRoutine = InvokeHandler.Instance.StartCoroutine(RunSpeakerV2());
                }
            }
            public void LiveSound(byte[] data) {
                SendSound(Target, Speaker.net.ID, data);
            }
            private IEnumerator RunSpeakerV2() {
                yield return new WaitForSeconds(.5f);
                while (_queuedSoundsV2.Count != 0) {
                    SoundDataV2 soundData = _queuedSoundsV2[0];
                    _queuedSoundsV2.RemoveAt(0);
                    LastTick = 0;
                    StartTime = DateTime.Now.Ticks;
                    for (int index = 0; index < soundData.Data.Count;) {
                        while (!WaitForNextSend() && index < soundData.Data.Count) {
                            SoundLibraryPacket data = soundData.Data[index];
                            SendSound(Target, Speaker.net.ID, data.SteamVoicePacket);
                            LastTick = data.TicksSinceStart;
                            index++;
                        }
                        yield return new WaitWhile(WaitForNextSend);
                    }
                    yield return new WaitForSeconds(1f);
                }
                Destroy();
            }
            private bool WaitForNextSend() {
                return DateTime.Now.Ticks - StartTime < LastTick;
            }
            private void SendSound(BasePlayer player, uint netId, byte[] data) {
                if (data.Length == 0) {
                    return;
                }
                NetWrite write = Net.sv.StartWrite();
                write.PacketID(Message.Type.VoiceData);
                write.UInt32(netId);
                write.BytesWithSize(data);
                write.Send(new SendInfo(player.Connection) {
                    priority = Priority.Immediate,
                }
                );
            }
            public void Destroy() {
                if (QueuedRoutine != null) {
                    InvokeHandler.Instance.StopCoroutine(QueuedRoutine);
                }
                Speaker.inventory.containerWear.Clear();
                Speaker.Kill();
                _pluginInstance?._playerSpeakers.Remove(Target.userID);
                _pluginInstance?._botSpeakers.Remove(NetId);
            }
        }
        private PlayerSpeaker GetPlayerSpeaker(BasePlayer player) {
            PlayerSpeaker speaker = _playerSpeakers[player.userID];
            //Added not null check in order to not queue up the sound files multiple times while entering/leaving zone, placeholder code until I implement a different method for the zones
            if (speaker != null) {
                return null;
            }
            speaker = new PlayerSpeaker(player);
            _playerSpeakers[player.userID] = speaker;
            return speaker;
        }
        private void SendLiveAudio(BasePlayer player, byte[] data) {
            PlayerSpeaker speaker = GetPlayerSpeaker(player);
            speaker.LiveSound(data);
        }
        private void SendLiveAudio(List<BasePlayer> players, byte[] data) {
            InvokeHandler.Instance.StartCoroutine(HandleLiveAudio(players, data));
        }
        private IEnumerator HandleLiveAudio(List<BasePlayer> players, byte[] data) {
            foreach (BasePlayer player in players) {
                SendLiveAudio(player, data);
                yield return null;
            }
        }
        private void SendLoadedAudioV2(BasePlayer player, SoundDataV2 soundData) {
            PlayerSpeaker speaker = GetPlayerSpeaker(player);
            if (speaker == null) {
                return;
            }
            speaker.QueueSoundV2(soundData);
        }
        private void SendLoadedAudio(IEnumerable<BasePlayer> players, SoundDataV2 soundData) {
            InvokeHandler.Instance.StartCoroutine(HandleCreateSpeaker(players, soundData));
        }
        private IEnumerator HandleCreateSpeaker(IEnumerable<BasePlayer> players, SoundDataV2 soundData) {
            foreach (BasePlayer player in players) {
                SendLoadedAudioV2(player, soundData);
                yield return null;
            }
        }
#endregion
#region Commands
        [ChatCommand("sl")]
        private void SoundLibraryChatCommand(BasePlayer player, string command, string[] args) {
            if (!permission.UserHasPermission(player.UserIDString, UsePermission)) {
                player.ChatMessage(Lang(LangKeys.NoPermission));
                return;
            }
            if (args.Length == 0) {
                player.ChatMessage(Lang(LangKeys.HelpText));
                return;
            }
            switch (args[0].ToLower()) {
                case "play" : {
                    HandlePlay(player, args);
                    break;
                }
                case "stop" : {
                    HandleStop(player, args);
                    break;
                }
                case "npc" : {
                    HandleNpc(player, args);
                    break;
                }
                case "zone" : {
                    HandleZone(player, args);
                    break;
                }
                default : {
                    player.ChatMessage(Lang(LangKeys.HelpText));
                    break;
                }
            }
        }
        [ChatCommand("audio")]
        private void AudioCommand(BasePlayer player, string command, string[] args) {
            if (!permission.UserHasPermission(player.UserIDString, AudioMessagesPermission)) {
                player.ChatMessage(Lang(LangKeys.NoPermission));
                return;
            }
            if (args.Length == 0) {
                player.ChatMessage(Lang(LangKeys.AudioMessagesHelpText));
                return;
            }
            switch (args[0].ToLower()) {
                case "help" : {
                    player.ChatMessage(Lang(LangKeys.AudioMessagesHelpText));
                    break;
                }
                case "send" : {
                    if (args.Length < 3) {
                        player.ChatMessage(Lang(LangKeys.AudioMessagesHelpText));
                        return;
                    }
                    BasePlayer target = FindPlayer(args[1]);
                    if (!target) {
                        player.ChatMessage(Lang(LangKeys.InvalidTarget));
                    }
                    string fileName = args[2];
                    if (fileName == null) {
                        player.ChatMessage(Lang(LangKeys.NullFileName));
                    }
                    SendSoundToPlayer(target.userID, fileName);
                    player.ChatMessage(Lang(LangKeys.PlayingAudioMessageText, null, fileName));
                    break;
                }
                case "sendall" : {
                    if (args.Length < 2) {
                        player.ChatMessage(Lang(LangKeys.AudioMessagesHelpText));
                        return;
                    }
                    string fileName = args[1];
                    if (fileName == null) {
                        player.ChatMessage(Lang(LangKeys.NullFileName));
                    }
                    SendSoundToAll(fileName);
                    player.ChatMessage(Lang(LangKeys.PlayingAudioMessageText, null, fileName));
                    break;
                }
                case "sendlooped" : {
                    if (args.Length < 4) {
                        player.ChatMessage(Lang(LangKeys.AudioMessagesHelpText));
                        return;
                    }
                    BasePlayer target = FindPlayer(args[1]);
                    if (!target) {
                        player.ChatMessage(Lang(LangKeys.InvalidTarget));
                    }
                    string fileName = args[2];
                    if (fileName == null) {
                        player.ChatMessage(Lang(LangKeys.NullFileName));
                    }
                    int loopTimes = Convert.ToInt32(args[3]);
                    SendSoundToPlayerLooped(target.userID, fileName, loopTimes);
                    player.ChatMessage(Lang(LangKeys.PlayingAudioMessageText, null, fileName));
                    break;
                }
                case "sendalllooped" : {
                    if (args.Length < 3) {
                        player.ChatMessage(Lang(LangKeys.AudioMessagesHelpText));
                        return;
                    }
                    string fileName = args[1];
                    if (fileName == null) {
                        player.ChatMessage(Lang(LangKeys.NullFileName));
                    }
                    int loopTimes = Convert.ToInt32(args[2]);
                    SendSoundToAllLooped(fileName, loopTimes);
                    player.ChatMessage(Lang(LangKeys.PlayingAudioMessageText, null, fileName));
                    break;
                }
                case "files" : {
                    string[] files = Interface.Oxide.DataFileSystem.GetFiles("SoundLibraryApi");
                    StringBuilder stringBuilder = new StringBuilder();
                    foreach (string file in files) {
                        if (file.Contains(".json")) {
                            continue;
                        }
                        stringBuilder.AppendLine(file.Split('\\').Last().Replace(".data", string.Empty));
                    }
                    player.ChatMessage(Lang(LangKeys.AvailableFileNames, null, stringBuilder));
                    break;
                }
            }
        }
        private void ConsoleAudioCommand(ConsoleSystem.Arg arg) {
            if (!arg.HasArgs()) {
                arg.ReplyWith(Lang(LangKeys.AudioMessagesHelpText));
                return;
            }
            switch (arg.Args[0].ToLower()) {
                case "help" : {
                    arg.ReplyWith(Lang(LangKeys.AudioMessagesHelpText));
                    break;
                }
                case "send" : {
                    if (arg.Args.Length < 3) {
                        arg.ReplyWith(Lang(LangKeys.AudioMessagesHelpText));
                        return;
                    }
                    BasePlayer target = FindPlayer(arg.Args[1]);
                    if (!target) {
                        arg.ReplyWith(Lang(LangKeys.InvalidTarget));
                        return;
                    }
                    string fileName = arg.Args[2];
                    if (fileName == null) {
                        arg.ReplyWith(Lang(LangKeys.NullFileName));
                        return;
                    }
                    SendSoundToPlayer(target.userID, fileName);
                    arg.ReplyWith(Lang(LangKeys.PlayingAudioMessageText, null, fileName));
                    break;
                }
                case "sendall" : {
                    if (arg.Args.Length < 2) {
                        arg.ReplyWith(Lang(LangKeys.AudioMessagesHelpText));
                        return;
                    }
                    string fileName = arg.Args[1];
                    if (fileName == null) {
                        arg.ReplyWith(Lang(LangKeys.NullFileName));
                        return;
                    }
                    SendSoundToAll(fileName);
                    arg.ReplyWith(Lang(LangKeys.PlayingAudioMessageText, null, fileName));
                    break;
                }
                case "sendlooped" : {
                    if (arg.Args.Length < 4) {
                        arg.ReplyWith(Lang(LangKeys.AudioMessagesHelpText));
                        return;
                    }
                    BasePlayer target = FindPlayer(arg.Args[1]);
                    if (!target) {
                        arg.ReplyWith(Lang(LangKeys.InvalidTarget));
                    }
                    string fileName = arg.Args[2];
                    if (fileName == null) {
                        arg.ReplyWith(Lang(LangKeys.NullFileName));
                    }
                    int loopTimes = Convert.ToInt32(arg.Args[3]);
                    SendSoundToPlayerLooped(target.userID, fileName, loopTimes);
                    arg.ReplyWith(Lang(LangKeys.PlayingAudioMessageText, null, fileName));
                    break;
                }
                case "sendalllooped" : {
                    if (arg.Args.Length < 3) {
                        arg.ReplyWith(Lang(LangKeys.AudioMessagesHelpText));
                        return;
                    }
                    string fileName = arg.Args[1];
                    if (fileName == null) {
                        arg.ReplyWith(Lang(LangKeys.NullFileName));
                    }
                    int loopTimes = Convert.ToInt32(arg.Args[2]);
                    SendSoundToAllLooped(fileName, loopTimes);
                    arg.ReplyWith(Lang(LangKeys.PlayingAudioMessageText, null, fileName));
                    break;
                }
                case "files" : {
                    string[] files = Interface.Oxide.DataFileSystem.GetFiles("SoundLibraryApi");
                    StringBuilder stringBuilder = new StringBuilder();
                    foreach (string file in files) {
                        if (file.Contains("NpcData")) {
                            continue;
                        }
                        stringBuilder.AppendLine(file.Split('\\').Last().Replace(".json", string.Empty));
                    }
                    arg.ReplyWith(Lang(LangKeys.AvailableFileNames, null, stringBuilder));
                    break;
                }
            }
        }
#endregion
#region Play Handler
        private void HandlePlay(BasePlayer player, string[] args) {
            if (args.Length < 2) {
                player.ChatMessage(Lang(LangKeys.PlayInvalidSyntax));
                return;
            }
            string name = string.Join(" ", args.Skip(1).ToArray());
            SoundDataV2 v2 = SoundDataV2.Load(name);
            if (v2 != null) {
                SendLoadedAudioV2(player, v2);
                player.ChatMessage(Lang(LangKeys.PlayingText, null, name));
                return;
            }
            player.ChatMessage(Lang(LangKeys.NoSoundFileFound, player, name));
        }
        private void HandleStop(BasePlayer player, string[] args) {
            GetPlayerSpeaker(player)?.Destroy();
        }
        private void HandleNpc(BasePlayer player, string[] args) {
            BasePlayer npc = FindNpc(player);
            if (!npc) {
                player.ChatMessage(Lang(LangKeys.NpcNotFound));
            }
            else {
                if (args.Length < 4) {
                    player.ChatMessage(Lang(LangKeys.HelpText));
                    return;
                }
                switch (args[1].ToLower()) {
                    case "add" : {
                        string action = args[2];
                        HookActionType hookActionType;
                        if (!Enum.TryParse(action, true, out hookActionType)) {
                            player.ChatMessage(Lang(LangKeys.InvalidHookActionType, null, action));
                            return;
                        }
                        string fileName = args[3];
                        if (fileName == null) {
                            player.ChatMessage(Lang(LangKeys.NullFileName));
                            return;
                        }
                        Hash<ulong, NpcData> npcData = _pluginData.NpcsData;
                        if (npcData.ContainsKey(npc.userID)) {
                            if (npcData[npc.userID].Filenames.ContainsKey(hookActionType)) {
                                if (npcData[npc.userID].Filenames[hookActionType].Contains(fileName)) {
                                    player.ChatMessage(Lang(LangKeys.FileNameAlreadyAdded, null, fileName));
                                    return;
                                }
                                npcData[npc.userID].Filenames[hookActionType].Add(fileName);
                            }
                            else {
                                npcData[npc.userID].Filenames.Add(hookActionType, new List<string> {
                                    fileName
                                }
                                );
                            }
                        }
                        else {
                            npcData.Add(npc.userID, new NpcData {
                                Filenames = new Hash<HookActionType, List<string>> {
                                    [hookActionType]
                                    = new List<string> {
                                        fileName
                                    }
                                }
                            }
                            );
                        }
                        player.ChatMessage(Lang(LangKeys.NpcSoundAdded, null, fileName, hookActionType));
                        SaveData();
                        break;
                    }
                    case "remove" : {
                        string action = args[2];
                        HookActionType hookActionType;
                        if (!Enum.TryParse(action, true, out hookActionType)) {
                            player.ChatMessage(Lang(LangKeys.InvalidHookActionType, null, action));
                            return;
                        }
                        string fileName = args[3];
                        if (fileName == null) {
                            player.ChatMessage(Lang(LangKeys.NullFileName));
                            return;
                        }
                        Hash<ulong, NpcData> npcData = _pluginData.NpcsData;
                        if (npcData.ContainsKey(npc.userID)) {
                            if (npcData[npc.userID].Filenames.ContainsKey(hookActionType)) {
                                if (npcData[npc.userID].Filenames[hookActionType].Contains(fileName)) {
                                    npcData[npc.userID].Filenames[hookActionType].Remove(fileName);
                                }
                            }
                        }
                        player.ChatMessage(Lang(LangKeys.NpcSoundRemoved, null, fileName, hookActionType));
                        SaveData();
                        break;
                    }
                }
            }
        }
        private void HandleZone(BasePlayer player, string[] args) {
            if (args.Length < 5) {
                player.ChatMessage(Lang(LangKeys.HelpText));
                return;
            }
            string zoneId = args[4];
            if (CheckZoneId(zoneId) == null) {
                player.ChatMessage(Lang(LangKeys.ZoneNotFound));
                return;
            }
            switch (args[1].ToLower()) {
                case "add" : {
                    string hookType = args[2];
                    ZoneHookType zoneHookType;
                    if (!Enum.TryParse(hookType, true, out zoneHookType)) {
                        player.ChatMessage(Lang(LangKeys.InvalidZoneHookType, null, hookType));
                        return;
                    }
                    string fileName = args[3];
                    if (fileName == null) {
                        player.ChatMessage(Lang(LangKeys.NullFileName));
                        return;
                    }
                    Hash<string, ZoneData> zoneData = _pluginData.ZonesData;
                    if (zoneData.ContainsKey(zoneId)) {
                        if (zoneData[zoneId].Filenames.ContainsKey(zoneHookType)) {
                            if (zoneData[zoneId].Filenames[zoneHookType].Contains(fileName)) {
                                player.ChatMessage(Lang(LangKeys.FileNameAlreadyAdded, null, fileName));
                                return;
                            }
                            zoneData[zoneId].Filenames[zoneHookType].Add(fileName);
                        }
                        else {
                            zoneData[zoneId].Filenames.Add(zoneHookType, new List<string> {
                                fileName
                            }
                            );
                        }
                    }
                    else {
                        zoneData.Add(zoneId, new ZoneData {
                            Filenames = new Hash<ZoneHookType, List<string>> {
                                [zoneHookType]
                                = new List<string> {
                                    fileName
                                }
                            }
                        }
                        );
                    }
                    player.ChatMessage(Lang(LangKeys.ZoneSoundAdded, null, fileName, zoneHookType, zoneId));
                    SaveData();
                    break;
                }
                case "remove" : {
                    string hookType = args[2];
                    ZoneHookType zoneHookType;
                    if (!Enum.TryParse(hookType, true, out zoneHookType)) {
                        player.ChatMessage(Lang(LangKeys.InvalidZoneHookType, null, hookType));
                        return;
                    }
                    string fileName = args[3];
                    if (fileName == null) {
                        player.ChatMessage(Lang(LangKeys.NullFileName));
                        return;
                    }
                    Hash<string, ZoneData> zoneData = _pluginData.ZonesData;
                    if (zoneData.ContainsKey(zoneId)) {
                        if (zoneData[zoneId].Filenames.ContainsKey(zoneHookType)) {
                            if (zoneData[zoneId].Filenames[zoneHookType].Contains(fileName)) {
                                zoneData[zoneId].Filenames[zoneHookType].Remove(fileName);
                            }
                        }
                    }
                    player.ChatMessage(Lang(LangKeys.ZoneSoundRemoved, null, fileName, zoneId));
                    SaveData();
                    break;
                }
            }
        }
#endregion
#region Configuration
        private class PluginConfig {
            [DefaultValue(true)]
            [JsonProperty(PropertyName = "Enable welcome message")]
            public bool WelcomeMessage {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Welcome message file name")]
            public List<string> WelcomeMessageFile {
                get;
                set;
            }
            [DefaultValue(true)]
            [JsonProperty(PropertyName = "Enable Chopper event message")]
            public bool ChopperMessage {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Chopper event message file name")]
            public List<string> ChopperMessageFile {
                get;
                set;
            }
            [DefaultValue(true)]
            [JsonProperty(PropertyName = "Enable Airdrop event message")]
            public bool AirdropMessage {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Airdrop event message file name")]
            public List<string> AirdropMessageFile {
                get;
                set;
            }
            [DefaultValue(true)]
            [JsonProperty(PropertyName = "Enable Cargoship event message")]
            public bool CargoshipMessage {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Cargoship event message file name")]
            public List<string> CargoshipMessageFile {
                get;
                set;
            }
            [DefaultValue(true)]
            [JsonProperty(PropertyName = "Enable Chinook event message")]
            public bool ChinookMessage {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Chinook event message file name")]
            public List<string> ChinookMessageFile {
                get;
                set;
            }
            [DefaultValue(true)]
            [JsonProperty(PropertyName = "Enable Crate Hack event message")]
            public bool CrateHackMessage {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Crate Hack event message file name")]
            public List<string> CrateHackMessageFile {
                get;
                set;
            }
            [DefaultValue(900f)]
            [JsonProperty(PropertyName = "Scheduled message interval (seconds)")]
            public float ScheduledMessageInterval {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Scheduled message file name")]
            public List<string> ScheduledMessageFile {
                get;
                set;
            }
            [DefaultValue(5f)]
            [JsonProperty(PropertyName = "Speaker Distance (The higher the number, the further away is the speaker resulting in a quieter voice)")]
            public float SpeakerDistance {
                get;
                set;
            }
        }
        protected override void LoadDefaultConfig() {
            PrintWarning("Loading Default Config");
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            Config.Settings.DefaultValueHandling = DefaultValueHandling.Populate;
            _pluginConfig = AdditionalConfig(Config.ReadObject<PluginConfig>());
            Config.WriteObject(_pluginConfig);
        }
        private PluginConfig AdditionalConfig(PluginConfig pluginConfig) {
            pluginConfig.WelcomeMessageFile = pluginConfig.WelcomeMessageFile ?? new List<string> {
                "filename1", "filename2", "filename3"
            }
            ;
            pluginConfig.ChopperMessageFile = pluginConfig.ChopperMessageFile ?? new List<string> {
                "filename1", "filename2", "filename3"
            }
            ;
            pluginConfig.AirdropMessageFile = pluginConfig.AirdropMessageFile ?? new List<string> {
                "filename1", "filename2", "filename3"
            }
            ;
            pluginConfig.CargoshipMessageFile = pluginConfig.CargoshipMessageFile ?? new List<string> {
                "filename1", "filename2", "filename3"
            }
            ;
            pluginConfig.ChinookMessageFile = pluginConfig.ChinookMessageFile ?? new List<string> {
                "filename1", "filename2", "filename3"
            }
            ;
            pluginConfig.CrateHackMessageFile = pluginConfig.CrateHackMessageFile ?? new List<string> {
                "filename1", "filename2", "filename3"
            }
            ;
            pluginConfig.ScheduledMessageFile = pluginConfig.ScheduledMessageFile ?? new List<string> {
                "filename1", "filename2", "filename3"
            }
            ;
            return pluginConfig;
        }
#endregion
#region Data Handler
        private void SaveData() {
            Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Data", _pluginData);
        }
        private void LoadData() {
            _pluginData = Interface.Oxide.DataFileSystem.ReadObject<PluginData>($"{Name}/Data");
            if (_pluginData == null) {
                _pluginData = new PluginData();
            }
        }
        private class PluginData {
            [JsonProperty(PropertyName = "Npc Data")]
            public Hash<ulong, NpcData> NpcsData {
                get;
                set;
            }
            = new Hash<ulong, NpcData>();
            [JsonProperty(PropertyName = "Zone Data")]
            public Hash<string, ZoneData> ZonesData {
                get;
                set;
            }
            = new Hash<string, ZoneData>();
        }
        private class NpcData {
            [JsonProperty(PropertyName = "Action type of the npc & Filenames that are played")]
            public Hash<HookActionType, List<string>> Filenames {
                get;
                set;
            }
        }
        private class ZoneData {
            [JsonProperty(PropertyName = "Zone hook type & Filenames that are played")]
            public Hash<ZoneHookType, List<string>> Filenames {
                get;
                set;
            }
        }
#endregion
#region Language
        private class LangKeys {
            public const string NoPermission = nameof(NoPermission);
            public const string HelpText = nameof(HelpText);
            public const string AudioMessagesHelpText = nameof(AudioMessagesHelpText);
            public const string InvalidAddSyntax = nameof(InvalidAddSyntax);
            public const string AddAlreadyExists = nameof(AddAlreadyExists);
            public const string PlayInvalidSyntax = nameof(PlayInvalidSyntax);
            public const string NoSoundFileFound = nameof(NoSoundFileFound);
            public const string PlayingText = nameof(PlayingText);
            public const string PlayingAudioMessageText = nameof(PlayingAudioMessageText);
            public const string InvalidTarget = nameof(InvalidTarget);
            public const string NullFileName = nameof(NullFileName);
            public const string FileNameNotFound = nameof(FileNameNotFound);
            public const string AvailableFileNames = nameof(AvailableFileNames);
            public const string NpcNotFound = nameof(NpcNotFound);
            public const string InvalidHookActionType = nameof(InvalidHookActionType);
            public const string InvalidZoneHookType = nameof(InvalidZoneHookType);
            public const string NpcSoundAdded = nameof(NpcSoundAdded);
            public const string NpcSoundRemoved = nameof(NpcSoundRemoved);
            public const string ZoneSoundAdded = nameof(ZoneSoundAdded);
            public const string ZoneSoundRemoved = nameof(ZoneSoundRemoved);
            public const string ZoneNotFound = nameof(ZoneNotFound);
            public const string FileNameAlreadyAdded = nameof(FileNameAlreadyAdded);
        }
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                [LangKeys.NoPermission]
                = "<color=#e3e3e3>You do not have permission to use this command</color>", [LangKeys.InvalidAddSyntax] = "<color=#e3e3e3>Invalid Syntax. Ex: <color=#de8732>/sl add soundname</color></color>", [LangKeys.AddAlreadyExists] = "<color=#e3e3e3>This sound already exists. </color>" + "<color=#e3e3e3>Please add <color=#de8732>overwrite</color> to your arguments to allow overwriting an existing sound.</color>" + "<color=#e3e3e3>Ex: <color=#de8732>sl add {{0}} overwrite</color></color>", [LangKeys.PlayInvalidSyntax] = "<color=#e3e3e3>Invalid Syntax. Ex: <color=#de8732>/sl play soundname</color> - to play the sound with the given name.</color>", [LangKeys.NoSoundFileFound] = "<color=#e3e3e3>No sound file found with name '{0}'</color>", [LangKeys.HelpText] = "<color=#e3e3e3>Allows players to record sound that can be played back to a player\n" + "<color=#de8732>/sl npc add hookActionType fileName</color> - to add one or more filenames to a human npc (hook action types are: <color=#de8732>OnUseNPC/OnEnterNPC/OnLeaveNPC/OnHitNPC</color>)\n" + "<color=#de8732>/sl npc remove hookActionType fileName</color> - to remove a filename from a human npc (hook action types are: <color=#de8732>OnUseNPC/OnEnterNPC/OnLeaveNPC/OnHitNPC</color>)\n" + "<color=#de8732>/sl zone add zoneHookType fileName zoneId</color> - to add one or more filenames to a zone (zone hook types are: <color=#de8732>OnEnterZone/OnExitZone</color>)\n" + "<color=#de8732>/sl zone remove zoneHookType fileName zoneId</color> - to remove a filename from a zone (zone hook types are: <color=#de8732>OnEnterZone/OnExitZone</color>)\n" + "<color=#de8732>/sl cancel</color> - to cancel your recording and not save.\n" + "<color=#de8732>/sl play</color> - to player your current recording back to you.\n" + "<color=#de8732>/sl</color> - to view this help text again.</color>", [LangKeys.AudioMessagesHelpText] = "<color=#e3e3e3><color=#66B2FF>/audio send playerName audioName</color> - Sends an audio message to a player</color>\n" + "<color=#e3e3e3><color=#66B2FF>/audio sendall audioName</color> - Sends an audio message to everyone on the server\n" + "<color=#e3e3e3><color=#66B2FF>/audio sendlooped playerName audioName 2 (loop times amount)</color> - Sends a looped audio message to a player\n" + "<color=#e3e3e3><color=#66B2FF>/audio sendalllooped audioName 2 (loop times amount)</color> - Sends a looped audio message to everyone on the server\n" + "<color=#e3e3e3><color=#66B2FF>/audio files</color> - Shows a list of all audio files on the server\n" + "<color=#e3e3e3><color=#66B2FF>/sl</color> - Shows the help page for the Sound Library API\n" + "<color=#e3e3e3><color=#66B2FF>/audio help</color> - Shows these help messages", [LangKeys.PlayingText] = "<color=#e3e3e3>Playing the file with the name of <color=#de8732>{0}</color></color>", [LangKeys.PlayingAudioMessageText] = "<color=#e3e3e3>Playing the file with the name of <color=#66B2FF>{0}</color></color>", [LangKeys.InvalidTarget] = "<color=#e3e3e3>Invalid target, try using his steamid/name</color>", [LangKeys.NullFileName] = "<color=#e3e3e3>This file name is null, use /audio files</color>", [LangKeys.AvailableFileNames] = "<color=#e3e3e3>Available files:\n<color=#66B2FF>{0}</color></color>", [LangKeys.FileNameNotFound] = "<color=#e3e3e3><color=#66B2FF>{0}</color> does not exist, use <color=#66B2FF>/audio files</color></color>", [LangKeys.NpcNotFound] = "<color=#e3e3e3>Couldn't find any human npc, make sure you have created one using <color=#de8732>/npc_add</color> and you are looking at it!</color>", [LangKeys.InvalidHookActionType] = "<color=#e3e3e3><color=#de8732>{0}</color> is invalid, list of hook action types:<color=#de8732>\nOnUseNPC\nOnEnterNPC\nOnLeaveNPC\nOnHitNPC</color></color>", [LangKeys.NpcSoundAdded] = "<color=#e3e3e3><color=#de8732>{0}</color> was added and will play when <color=#66B2FF>{1}</color> is triggered</color>", [LangKeys.NpcSoundRemoved] = "<color=#e3e3e3><color=#de8732>{0}</color> was removed from this NPC!</color>", [LangKeys.InvalidZoneHookType] = "<color=#e3e3e3><color=#de8732>{0}</color> is invalid, list of zone hook types:<color=#de8732>\nOnEnterZone\nOnExitZone</color></color>", [LangKeys.ZoneSoundAdded] = "<color=#e3e3e3><color=#de8732>{0}</color> was added and will play when <color=#66B2FF>{1}</color> is triggered (Zone ID: {2})</color>", [LangKeys.ZoneSoundRemoved] = "<color=#e3e3e3><color=#de8732>{0}</color> was removed from this Zone ({1})!</color>", [LangKeys.ZoneNotFound] = "<color=#e3e3e3>Zone not found!</color>", [LangKeys.FileNameAlreadyAdded] = "<color=#e3e3e3><color=#de8732>{0}</color> was already added!</color>"
            }
            , this);
        }
        private string Lang(string key, BasePlayer player = null, params object[] args) {
            try {
                return string.Format(lang.GetMessage(key, this, player?.UserIDString), args);
            }
            catch (Exception ex) {
                PrintError($"Lang Key '{key}' threw exception\n:{ex}");
                throw;
            }
        }
#endregion
#region API
        private void SendSoundToPlayer(ulong playerId, string name) {
            if (string.IsNullOrEmpty(name)) {
                return;
            }
            BasePlayer player = BasePlayer.FindAwakeOrSleeping(playerId.ToString());
            if (!player || !player.IsConnected) {
                return;
            }
            SoundDataV2 data = SoundDataV2.Load(name);
            if (data == null) {
                return;
            }
            SendLoadedAudioV2(player, data);
            player.ChatMessage(Lang(LangKeys.PlayingText, null, name));
        }
        private void SendSoundToPlayers(List<BasePlayer> players, string name) {
            if (string.IsNullOrEmpty(name)) {
                return;
            }
            SoundDataV2 data = SoundDataV2.Load(name);
            if (data == null) {
                return;
            }
            SendLoadedAudio(players, data);
        }
        private void SendSoundToAll(string name) {
            if (string.IsNullOrEmpty(name)) {
                return;
            }
            SoundDataV2 da
// ... [Code preview truncated due to length. Full source in attached file] ...

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху