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

FREE TirifyGamePluginRust : 1.8.2 1.8.2

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// -------------- PLUGIN CODE MACROSES --------------
// If you want to select and older version for the plugin, remove '//' near your version:
//#define RUST_DEVBLOG_198
//#define RUST_DEVBLOG_266
#if RUST_DEVBLOG_198
//#define USE_HARMONY
#define RUST_OLD_STEAM_AUTH
#define RUST_DISABLE_EASYANTICHEAT
#define OLD_NETWORKABLE
#define OLD_ITEMS
//#define RUST_OLD_HARMONY
//#define RUST_ORIGINAL_WIPE_ID
//#define RUST_TEAMS
//#define RUST_NPC
#define RUST_OLD_STEAMWORKS
#define RUST_NO_HELICOPTERS
#elif RUST_DEVBLOG_266
//#define USE_HARMONY
#define RUST_OLD_STEAM_AUTH
//#define RUST_DISABLE_EASYANTICHEAT
//#define RUST_OLD_HARMONY
//#define RUST_ORIGINAL_WIPE_ID
#define RUST_TEAMS
#define RUST_NPC
#define RUST_NO_HELICOPTERS
//#define RUST_OLD_STEAMWORKS
//#define OLD_ITEMS
#define OLD_NETWORKABLE
#else
#define RUST_LATEST
#define USE_HARMONY
//#define RUST_OLD_STEAM_AUTH
//#define RUST_DISABLE_EASYANTICHEAT
//#define RUST_OLD_HARMONY
#define RUST_ORIGINAL_WIPE_ID
#define RUST_TEAMS
#define RUST_NPC
//#define RUST_OLD_STEAMWORKS
#endif
//#define STAGE
#if USE_HARMONY
#if RUST_OLD_HARMONY
using Harmony;
#else
using HarmonyLib;
#endif
#endif
// -------------- PLUGIN CODE MACROSES --------------
using Network;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
using WebSocketSharp;
using WebSocketSharp.Net;
// ReSharper disable All
#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value
#pragma warning disable CS0168 // Variable is declared but never used
// Reference: 0Harmony
namespace Oxide.Plugins {
    [Info("TirifyGamePluginRust", "Tirify Inc.", "1.8.2")]
    public class TirifyGamePluginRust : RustPlugin {
        public static TirifyGamePluginRust Singleton;
        public const uint UpdateInterval = 30;
        public const int PlayerAfkTime = 300;
        public const int AppIdOffset = 72;
        public const float SocketReconnectInterval = 60f;
        internal readonly static HashSet<ulong> _openedLootables = new HashSet<ulong>();
        private static ServerStats _serverStats;
        private static FrameLoggerComponent _frameObject;
        private static Timer _updateTimer;
        private static Timer _statsTimer;
        private static Timer _eventTimer;
        private static Timer _frameTimer;
        private static Timer _playerStatTimer;
        [PluginReference]
        private Plugin TGPP;
        [PluginReference]
        private Plugin IQReportSystem;
#region [ Permissions ]
        private const string PermissionBanUnban = "tirify.banunban";
#endregion
#region [ Hooks ]
        private void OnServerInitialized() {
            try {
                InitializeReflection();
                RegisterServer();
                RegisterWebSocket();
                RegisterEventWorker();
                RegisterFrameLogger();
                //RegisterPlayerStats();
                EventLogger.LogServerStarted();
            }
            catch (Exception ex) {
                PrintError($"Не удалось инициализировать плагин.{ex.Message}");
                NextTick(() => Interface.Oxide.UnloadPlugin(this.Name));
            }
        }
        private void Loaded() {
            Singleton = this;
        }
        private void Unload() {
            _updateTimer?.Destroy();
            _statsTimer?.Destroy();
            _eventTimer?.Destroy();
            _frameTimer?.Destroy();
            _playerStatTimer?.Destroy();
            _serverStats?.Disconnect();
            UnityEngine.Object.Destroy(_frameObject);
        }
        private object OnUserApprove(Connection connection) {
            string reason = null;
            if (TirifyBanSystem.CheckPlayerBanned(connection, out reason)) {
                if (_config.BanSystem.ShowBanReason) {
                    ConnectionAuth.Reject(connection, $"You are banned! Reason: {reason}");
                }
                else {
                    ConnectionAuth.Reject(connection, "You are banned!", $"You are banned! Reason: {reason}");
                }
                return false;
            }
            return null;
        }
        private void OnClientDisconnected(Connection connection, string reason) {
            if (connection == null || connection.state != Connection.State.Welcoming) {
                return;
            }
            try {
                EventLogger.LogPlayerConnection(connection, "leave", reason);
                API.Player.OnDisconnect(connection.userid);
            }
            catch (Exception ex) {
                Singleton.PrintError($"Exception in OnClientDisconnected: {ex}");
            }
        }
        private void OnPlayerChat(BasePlayer player, string message, object channel = null) => EventLogger.LogChatMessage(player, channel?.ToString()?.ToLower() ?? "global", message);
#if RUST_TEAMS
        private void OnTeamCreated(BasePlayer player, RelationshipManager.PlayerTeam team) => EventLogger.LogTeam(player, team.teamID.ToString(), "create", new string[0]);
        private void OnTeamKick(RelationshipManager.PlayerTeam team, BasePlayer player, ulong target) => EventLogger.LogTeam(player, team.teamID.ToString(), "kick", team.members.Select(f => f.ToString()).ToArray(), target);
        private void OnTeamAcceptInvite(RelationshipManager.PlayerTeam team, BasePlayer player) => EventLogger.LogTeam(player, team.teamID.ToString(), "join", team.members.Select(f => f.ToString()).ToArray());
        private void OnTeamLeave(RelationshipManager.PlayerTeam team, BasePlayer player) => EventLogger.LogTeam(player, team.teamID.ToString(), "leave", team.members.Select(f => f.ToString()).ToArray());
#endif
        private void OnCupboardAuthorize(BuildingPrivlidge privilege, BasePlayer player) => EventLogger.LogCupboard(player, privilege.buildingID.ToString(), "join", privilege.authorizedPlayers.Select(f => f.userid.ToString()).ToArray());
        private void OnCupboardClearList(BuildingPrivlidge privilege, BasePlayer player) {
            EventLogger.LogCupboard(player, privilege.buildingID.ToString(), "clear", privilege.authorizedPlayers.Select(f => f.userid.ToString()).ToArray());
            OnCupboardRaided(privilege, player);
        }
        private void OnCupboardDeauthorize(BuildingPrivlidge privilege, BasePlayer player) => EventLogger.LogCupboard(player, privilege.buildingID.ToString(), "leave", privilege.authorizedPlayers.Select(f => f.userid.ToString()).ToArray());
        private void OnPlayerReported(BasePlayer reporter, string targetName, string targetId, string subject, string message, string type) {
            ulong targetSteamId = 0;
            if (!ulong.TryParse(targetId, out targetSteamId) || targetSteamId == 0) {
                return;
            }
            EventLogger.LogReport(reporter, targetSteamId, subject, message);
        }
        private void OnEntityDeath(BaseCombatEntity entity, HitInfo info) {
            if (entity == null) {
                return;
            }
            bool wasWounded = entity is BasePlayer && (entity as BasePlayer).IsWounded();
            NextTick(() => {
                try {
                    if (entity is BasePlayer) {
#if RUST_NPC
                        if ((entity as BasePlayer).IsNpc == true) {
                            return;
                        }
#endif
                        OnPlayerDie(entity as BasePlayer, info, wasWounded);
                        return;
                    }
                    if (info == null || info.InitiatorPlayer == null) {
                        return;
                    }
                    string entityCategory = null;
                    if (entity is BradleyAPC) {
                        OnBradleyApcDeath(entity as BradleyAPC, info);
                        entityCategory = "tank";
                    }
#if !RUST_NO_HELICOPTERS
                    else if (entity is PatrolHelicopter) {
                        entityCategory = "patrolhelicopter";
                    }
#endif
                    else if (entity is BuildingPrivlidge) {
                        var cupboard = entity as BuildingPrivlidge;
                        if (cupboard.IsAuthed(info.InitiatorPlayer)) {
                            return;
                        }
                        OnCupboardRaided(cupboard, info.InitiatorPlayer);
                    }
                    else if (entity is BaseAnimalNPC) {
                        entityCategory = "animal";
                    }
                    else if (entity is NPCPlayer) {
                        entityCategory = "npc";
                    }
                    if (entityCategory != null) {
                        PlayerStats.Increment(info.InitiatorPlayer, $"kill:{entityCategory}");
                    }
                }
                catch {
                }
            }
            );
        }
        private void OnPlayerDie(BasePlayer victimPlayer, HitInfo info, bool wounded) {
#if RUST_NPC
            if (victimPlayer?.IsNpc == true || victimPlayer?.userID < 765600000000) {
                return;
            }
#endif
            float logTime = 30f;
            if (wounded) {
                logTime += 50f;
            }
            var playerCombatLog = PlayerCombatLog.Create(victimPlayer, true, logTime);
            // not from player
            if (playerCombatLog == null) {
                if (info == null || info.Initiator == null) {
                    EventLogger.LogDeath(victimPlayer, victimPlayer.lastDamage.ToString().ToLower());
                    return;
                }
                if (victimPlayer.net?.ID == info.Initiator.net?.ID) {
                    EventLogger.LogDeath(victimPlayer, "suicide");
                    return;
                }
#if RUST_NPC
#if !RUST_NO_HELICOPTERS
                if (info.Initiator is PatrolHelicopter) {
                    EventLogger.LogDeath(victimPlayer, "helicopter");
                }
#else
                if (false) {
                }
#endif
                else if (info.Initiator is BradleyAPC) {
                    EventLogger.LogDeath(victimPlayer, "tank");
                }
                else if (info.Initiator is CH47Helicopter) {
                    EventLogger.LogDeath(victimPlayer, "ch47helicopter");
                }
                else if (info.Initiator is BradleyAPC) {
                    EventLogger.LogDeath(victimPlayer, "tank");
                }
                else if (info.Initiator is BaseAnimalNPC) {
                    EventLogger.LogDeath(victimPlayer, "animal", info.Initiator.Categorize());
                }
                else if (info.Initiator is NPCPlayer) {
                    EventLogger.LogDeath(victimPlayer, "npc", info.Initiator.ShortPrefabName);
                }
                else {
                    EventLogger.LogDeath(victimPlayer, "unknown", info.Initiator.ShortPrefabName);
                }
            }
            // From player (has combatlog)
            else {
                EventLogger.LogCombatLog(playerCombatLog);
                var attackerPlayer = TirifyGameExt.FindAwakeOrSleeping(playerCombatLog.AttackerSteamId);
                EventLogger.LogKill(victimPlayer, attackerPlayer, playerCombatLog.Weapon, playerCombatLog.Bone, playerCombatLog.Distance, playerCombatLog);
            }
#endif
        }
        private void OnBradleyApcDeath(BradleyAPC bradley, HitInfo info) {
            var assistants = GetEntityAssistants(bradley, info.InitiatorPlayer);
            var assistantIds = assistants.Select(f => f.UserIDString).ToList();
            assistantIds.Add(info.InitiatorPlayer.UserIDString);
            var fullTeamList = string.Join(",", assistantIds.ToArray());
            string weaponName = info.Weapon?.GetItem()?.info?.shortname;
            string grid = TirifyGameExt.GetGrid(bradley.transform.position);
            string distance = ((int)bradley.Distance(info.InitiatorPlayer)).ToString();
            EventLogger.LogEventNpcKilled("bradley", info.InitiatorPlayer, fullTeamList, weaponName, grid, distance);
            foreach (var assistant in assistants) {
                EventLogger.LogEventNpcAssisted("bradley", assistant, fullTeamList, weaponName, grid, distance, info.InitiatorPlayer.UserIDString);
            }
        }
#if !RUST_NO_HELICOPTERS
        private void OnPatrolHelicopterKill(PatrolHelicopter heli, HitInfo info) {
            if (heli == null || info == null || info.InitiatorPlayer == null) {
                return;
            }
            var assistants = GetEntityAssistants(heli, info.InitiatorPlayer);
            var fullTeamList = string.Join(",", assistants.Select(f => f.UserIDString).Append(info.InitiatorPlayer.UserIDString));
            string weaponName = info.Weapon?.GetItem()?.info?.shortname;
            string grid = TirifyGameExt.GetGrid(heli.transform.position);
            string distance = ((int)heli.Distance(info.InitiatorPlayer)).ToString();
            EventLogger.LogEventNpcKilled("patrolhelicopter", info.InitiatorPlayer, fullTeamList, weaponName, grid, distance);
            foreach (var assistant in assistants) {
                EventLogger.LogEventNpcAssisted("patrolhelicopter", assistant, fullTeamList, weaponName, grid, distance, info.InitiatorPlayer.UserIDString);
            }
        }
#endif
        private void OnCupboardRaided(BuildingPrivlidge buildingBlock, BasePlayer initiatorPlayer) {
#if RUST_TEAMS
            // if team's cupboard
            if (initiatorPlayer.Team != null) {
                foreach (var member in buildingBlock.authorizedPlayers) {
                    if (initiatorPlayer.Team.members.Contains(member.userid)) {
                        return;
                    }
                }
            }
#endif
            if (buildingBlock.OwnerID == initiatorPlayer.userID || buildingBlock.GetProtectedSeconds() > 0) {
                return;
            }
            var assistants = GetEntityAssistants(buildingBlock, initiatorPlayer);
            var assistantIds = assistants.Select(f => f.UserIDString).ToList();
            assistantIds.Add(initiatorPlayer.UserIDString);
            var fullTeamList = string.Join(",", assistantIds.ToArray());
            string grid = TirifyGameExt.GetGrid(buildingBlock.transform.position);
            string oldAuthed = string.Join(",", buildingBlock.authorizedPlayers.Select(f => f.userid.ToString()).ToArray());
            string inventoryItems = string.Join(",", TirifyGameExt.SerializeForSocket(buildingBlock.inventory));
            EventLogger.LogCupboardRaided(initiatorPlayer, fullTeamList, oldAuthed, grid, inventoryItems);
            foreach (var assistant in assistants) {
                EventLogger.LogCupboardRaidedAssist(assistant, fullTeamList, oldAuthed, grid, inventoryItems, initiatorPlayer.UserIDString);
            }
        }
        private void OnPlayerConnected(BasePlayer player) {
            if (player.IsReceivingSnapshot) {
                NextTick(() => OnPlayerConnected(player));
                return;
            }
            EventLogger.LogPlayerConnection(player.Connection, "join");
            PlayerStats.Increment(player, "join:server");
            byte[] token = player.Connection.token;
            LogTokenToFile(player.displayName, player.UserIDString, token);
            API.Player.OnConnected(TirifyGameExt.ToHexString(token));
        }
        private void LogTokenToFile(string username, string steamId, byte[] token) {
            try {
                string tokenHex = TirifyGameExt.ToHexString(token);
                string logPath = $"{Interface.Oxide.RootDirectory}/oxide/data/tirify_tokens.log";
                using (var sw = new System.IO.StreamWriter(logPath, true)) {
                    sw.WriteLine(tokenHex);
                }
            }
            catch (Exception ex) {
                PrintWarning($"Ошибка при логировании токена: {ex.Message}");
            }
        }
        private void OnServerUserSet(ulong uid, global : : ServerUsers.UserGroup group, string username, string notes, long expiry) {
            var user = BasePlayer.FindByID(uid);
            if (user != null && group == ServerUsers.UserGroup.Banned) {
                EventLogger.LogBan(user);
            }
        }
        private void OnPlayerViolation(BasePlayer player, AntiHackType type, float amount) {
            if (type == AntiHackType.ProjectileHack) {
                return;
            }
            var totalViolation = player.violationLevel + amount;
            // Ignore noclip or speedhack unless it reachs kick value
            if ((type == AntiHackType.NoClip || type == AntiHackType.SpeedHack) && totalViolation < ConVar.AntiHack.maxviolation) {
                return;
            }
            EventLogger.LogPlayerViolation(player, type.ToString(), amount);
        }
        private void OnStashExposed(StashContainer stash, BasePlayer player) {
            if (stash.OwnerID.ToString() != player.UserIDString) {
                BasePlayer target = BasePlayer.Find(stash.OwnerID.ToString());
                EventLogger.LogStashExposed(player, stash, target, target == null ? stash.OwnerID.ToString() : null);
            }
        }
        private void OnPluginLoaded(Plugin plugin) {
            if (plugin != null && plugin != this) {
                EventLogger.LogPluginLoad(plugin, "load");
            }
        }
        private void OnPluginUnloaded(Plugin plugin) {
            if (plugin != null && plugin != this) {
                EventLogger.LogPluginLoad(plugin, "unload");
            }
        }
        private void OnEntitySpawned(BaseNetworkable entity) {
#if !RUST_NO_HELICOPTERS
            if (entity is CargoShip) {
                EventLogger.LogEventSpawn("cargo");
            }
            if (entity is PatrolHelicopter) {
                EventLogger.LogEventSpawn("patrolhelicopter");
            }
            if (entity is CH47Helicopter) {
                EventLogger.LogEventSpawn("ch47");
            }
#endif
            if (entity is BradleyAPC) {
                EventLogger.LogEventSpawn("tank");
            }
        }
#if RUST_LATEST
        private void OnCrateHack(HackableLockedCrate crate) {
            var assistants = GetEntityAssistants(crate, crate.originalHackerPlayer);
            var fullTeamList = string.Join(",", assistants.Select(f => f.UserIDString).Append(crate.originalHackerPlayer.UserIDString));
            string grid = TirifyGameExt.GetGrid(crate.transform.position);
            EventLogger.LogCrateHackStart(crate.originalHackerPlayer, fullTeamList, grid);
            foreach (var assistant in assistants) {
                EventLogger.LogCrateHackAssisted(assistant, fullTeamList, grid, crate.originalHackerPlayer.UserIDString);
            }
        }
#endif
        private void OnLootEntity(BasePlayer player, BaseEntity entity) {
            try {
#if OLD_NETWORKABLE
                var entityId = entity.net.ID;
#else
                var entityId = entity.net.ID.Value;
#endif
                if (_openedLootables.Contains(entityId)) {
                    return;
                }
                bool looted = false;
#if RUST_LATEST
                if (entity is HackableLockedCrate) {
                    OnPlayerLootLockedCrate(entity as HackableLockedCrate, player);
                    looted = true;
                }
#endif
                if (entity is SupplyDrop) {
                    OnPlayerLootSupplyDrop(entity as SupplyDrop, player);
                    looted = true;
                }
                else if (entity is PlayerCorpse) {
                    var corpse = entity as PlayerCorpse;
                    if (corpse.playerSteamID != player.userID) {
                        OnPlayerLootPlayerCorpse(entity as PlayerCorpse, player);
                        looted = true;
                    }
                }
                if (looted) {
                    _openedLootables.Add(entityId);
                }
            }
            catch {
            }
        }
#if RUST_LATEST
        private void OnPlayerLootLockedCrate(HackableLockedCrate crate, BasePlayer player) {
            var assistants = GetEntityAssistants(crate, player);
            var fullTeamList = string.Join(",", assistants.Select(f => f.UserIDString).Append(player.UserIDString));
            string inventory = string.Join(",", TirifyGameExt.SerializeForSocket(crate.inventory));
            string grid = TirifyGameExt.GetGrid(crate.transform.position);
            EventLogger.LogPlayerLootLockedCrate(player, fullTeamList, grid, inventory);
            foreach (var assistant in assistants) {
                EventLogger.LogPlayerLootLockedCrateAssist(assistant, fullTeamList, grid, inventory, player.UserIDString);
            }
        }
#endif
        private void OnPlayerLootSupplyDrop(SupplyDrop drop, BasePlayer player) {
            var assistants = GetEntityAssistants(drop, player);
            var assistantIds = assistants.Select(f => f.UserIDString).ToList();
            assistantIds.Add(player.UserIDString);
            var fullTeamList = string.Join(",", assistantIds.ToArray());
            string inventoryItems = string.Join(",", TirifyGameExt.SerializeForSocket(drop.inventory));
            string grid = TirifyGameExt.GetGrid(drop.transform.position);
            EventLogger.LogPlayerLootSupplyDrop(player, fullTeamList, grid, inventoryItems);
            foreach (var assistant in assistants) {
                EventLogger.LogPlayerLootSupplyDropAssist(assistant, fullTeamList, grid, inventoryItems, player.UserIDString);
            }
        }
        private void OnPlayerLootPlayerCorpse(PlayerCorpse playerCorpse, BasePlayer player) {
            try {
                var assistants = GetEntityAssistants(playerCorpse, player);
                var assistantIds = assistants.Select(f => f.UserIDString).ToList();
                assistantIds.Add(player.UserIDString);
                var fullTeamList = string.Join(",", assistantIds.ToArray());
                var containersItems = playerCorpse.containers.Select(f => string.Join(",", TirifyGameExt.SerializeForSocket(f)));
                string inventoryItems = string.Join(";", containersItems.ToArray());
                string grid = TirifyGameExt.GetGrid(playerCorpse.transform.position);
                EventLogger.LogPlayerLootCorpse(player, fullTeamList, grid, inventoryItems);
                foreach (var assistant in assistants) {
                    EventLogger.LogPlayerLootCorpseAssist(assistant, fullTeamList, grid, inventoryItems, player.UserIDString);
                }
            }
            catch {
            }
        }
        private void OnPlayerWound(BasePlayer player, HitInfo info) {
            if (player == null || info == null || info.InitiatorPlayer == null || info.InitiatorPlayer.IsNpc) {
                return;
            }
            EventLogger.LogPlayerWounded(info.InitiatorPlayer, player);
        }
        private void OnPlayerAssist(BasePlayer target, BasePlayer player) {
            PlayerStats.Increment(player, "upwounded:player");
        }
        private void OnCargoPlaneSignaled(CargoPlane cargoPlane, SupplySignal supplySignal) {
            var playerOwner = supplySignal.GetItem()?.GetRootContainer()?.playerOwner;
            if (playerOwner != null) {
                PlayerStats.Increment(playerOwner, "use:supply");
            }
        }
        private void OnHealingItemUse(MedicalTool tool, BasePlayer player) {
            PlayerStats.Increment(player, $"use:{tool.GetItem()?.info?.shortname}");
        }
        private void OnExplosiveThrown(BasePlayer player, BaseEntity entity, ThrownWeapon item) {
            PlayerStats.Increment(player, $"use:{item.GetItem()?.info?.shortname}");
        }
        private void OnPlayerCommand(BasePlayer player, string command, string[] args) {
            switch (command.ToLower()) {
                case "pm" : {
                    if (args.Length > 1) {
                        string playerSearch = args[0];
                        BasePlayer receiver = BasePlayer.Find(playerSearch);
                        if (receiver != null) {
                            EventLogger.LogChatMessage(player, "pm", string.Join(" ", args.Skip(1).ToArray()), receiver);
                        }
                    }
                    break;
                }
                case "r" : {
                    EventLogger.LogChatMessage(player, "pm", string.Join(" ", args));
                    break;
                }
            }
            EventLogger.LogPlayerCommand(player, command, args);
        }
        private void OnTirifyUseBan(string steamId, string reason, BasePlayer moderator = null) {
            EventLogger.LogBan(steamId, reason, moderator);
        }
        private void OnTirifyUseUnBan(string steamId, BasePlayer moderator = null) {
            EventLogger.LogUnban(steamId, moderator);
        }
#endregion
#region [ API ]
        public class API {
            public static class URL {
                public const string WebSocket = "server-stats";
                public const string Auth = "server-player-auth";
                public const string Ban = "server-player-ban";
                public const string Events = "server-player-event";
                public const string PlayerStats = "player-stats";
                public const string GameServer = "game-server-gateway";
                public const string GameServerPlayers = "game-server-p";
                public const string Gateway = "/gateway";
                internal readonly static Dictionary<string, List<string>> _urls = new Dictionary<string, List<string>>() {
                    {
                        WebSocket, new List<string>() {
                            "wss://s01-server-stats-gateway.tirify.com/api/v1/server/websocket",
                        }
                    }
                    , {
                        Auth, new List<string>() {
                            "https://s01-server-player-auth-gateway.tirify.com/api",
                        }
                    }
                    , {
                        Ban, new List<string>() {
                            "https://s01-server-player-ban-gateway.tirify.com/api/v1/server/ban",
                        }
                    }
                    , {
                        Events, new List<string>() {
                            "https://s01-server-player-event-gateway.tirify.com/api/v1/player/events",
                        }
                    }
                    , {
                        PlayerStats, new List<string>() {
                            "https://s01-player-stats-gateway.tirify.com/api/v1/player/event",
                        }
                    }
                    , {
                        GameServer, new List<string>() {
                            "https://s01-game-server-gateway.tirify.com",
                        }
                    }
                    , {
                        GameServerPlayers, new List<string>() {
                            "https://s01-game-server-p-gateway.tirify.com",
                        }
                    }
                    , {
                        Gateway, new List<string>() {
                            "https://gateway.tirify.com",
                        }
                    }
                }
                ;
                public static int CurrentServer {
                    get;
                    internal set;
                }
                public static string Get(string name, int index = 0) {
                    // out of range
                    if (index >= _urls.Count) {
                        return null;
                    }
                    var url = _urls[name].ElementAtOrDefault(index);
                    if (url == null) {
                        return Get(name, index - 1);
                    }
                    return url;
                }
                public static string GetCurrent(string name) {
                    var url = Get(name, CurrentServer);
#if STAGE
                    if (!url.Contains("-in-stage.tirify.com")) {
                        url = url.Replace(".tirify.com", "-in-stage.tirify.com");
                    }
                    // для стейджа нет прокси
                    if (url.Contains("proxy01")) {
                        url = url.Replace("proxy01", "s01");
                    }
#endif
                    return url;
                }
            }
            public static class Player {
                private static string PlayerJoinUrl => URL.GetCurrent(URL.GameServerPlayers) + "/api/v3/player/join";
                private static string PlayerJoinManyUrl => URL.GetCurrent(URL.GameServerPlayers) + "/api/v3/player/joinmany";
                private static string PlayerLeaveUrl => URL.GetCurrent(URL.GameServerPlayers) + "/api/v3/player/leave";
                public static void OnConnected(string playerToken) {
                    try {
                        var content = JsonConvert.SerializeObject(new {
                            playerToken
                        }
                        );
                        SendPostRequest(GetRandomServerUrl(PlayerJoinUrl), content, string.Empty);
                    }
                    catch {
                    }
                }
                public static void OnConnected(List<string> playersTokens) {
                    try {
                        var content = JsonConvert.SerializeObject(new {
                            playersTokens
                        }
                        );
                        SendPostRequest(GetRandomServerUrl(PlayerJoinManyUrl), content, string.Empty);
                    }
                    catch {
                    }
                }
                public static bool OnDisconnect(ulong steamId) {
                    try {
                        var content = JsonConvert.SerializeObject(new {
                            steamId
                        }
                        );
                        SendPostRequest(GetRandomServerUrl(PlayerLeaveUrl), content, steamId.ToString());
                        return true;
                    }
                    catch {
                        Singleton.RegisterServer();
                    }
                    return false;
                }
                public static void SendStats(string serialized) {
                    try {
#if STAGE
                        Singleton.Puts(serialized);
#endif
                        SendPostRequest(GetRandomServerUrl(URL.GetCurrent(URL.PlayerStats)), serialized, "");
                    }
                    catch (Exception) {
                    }
                }
                public static void OnlineHeartbeat(int piratesCount, Action<bool> callbackNeedRestart) {
                    var url = GetRandomServerUrl(URL.GetCurrent(URL.GameServerPlayers)) + $"/api/v1/server/{_config.ServerApiKey}/heartbeat?online={piratesCount}";
                    Singleton.webrequest.Enqueue(url, string.Empty, (code, response) => {
                        try {
                            if (code >= 300 || string.IsNullOrEmpty(response)) {
                                return;
                            }
#if STAGE
                            Singleton.Puts($"Heartbeat: {response}");
#endif
                            var responseObject = JsonConvert.DeserializeObject<Dictionary<string, object>>(response);
                            if (responseObject.ContainsKey("success")) {
                                bool success = (bool)responseObject["success"];
                                callbackNeedRestart(!success);
                            }
                        }
                        catch {
                        }
                    }
                    , Singleton);
                }
            }
            public static class Server {
                private static string AuthStartupUrl => string.Concat(URL.GetCurrent(URL.GameServer), "/api/v1/server/init");
                private static string PairUrl => string.Concat(URL.GetCurrent(URL.Gateway), "/api/v1/project/server/pair");
                public static void Init(Action<int, string> callback = null) {
                    try {
                        var content = GetServerInfo();
#if STAGE
                        Singleton.Puts(content);
#endif
                        SendPostRequest(GetRandomServerUrl(AuthStartupUrl), content, _config.ServerApiKey, callback);
                    }
                    catch {
                        Singleton.RegisterServer();
                    }
                }
                public static void Pair(string inviteKey, Action<int, string> callback) {
                    try {
                        var content = JsonConvert.SerializeObject(new {
                            inviteKey, serverKey = _config.ServerApiKey
                        }
                        );
                        SendPostRequest(PairUrl, content, _config.ServerApiKey, callback);
                    }
                    catch (Exception ex) {
                        Singleton.PrintError($"Exception in server pairing: {ex}");
                    }
                }
                private static string GetServerInfo() {
                    return JsonConvert.SerializeObject(new {
                        ip = Singleton.GetServerIp(), gamePort = ConVar.Server.port, queryPort = ConVar.Server.queryport, serverName = ConVar.Server.hostname, maxPlayers = ConVar.Server.maxplayers, mapName = ConVar.Server.level, mapSize = ConVar.Server.worldsize.ToString(), gameType = "rust", version = Rust.Protocol.network.ToString(), serverToken = _config.ServerToken, wid = Singleton.GetServerWipeId(), rid = Singleton.GetRestartId(), has_tirify_license_plugin = Singleton.plugins.Exists("TGPP"), has_tiriry_partner_plugin = Singleton.plugins.Exists("TirifyLauncherPartner"), has_fgs_plugin = Singleton.plugins.Exists("FGS"), discordLink = _config.UrlVk, donateShopLink = _config.UrlShop, vkGroupLink = _config.UrlDiscord,
#if RUST_OLD_STEAMWORKS
                        serverTags = Facepunch.Steamworks.Server.Instance.GameTags,
#else
                        serverTags = Steamworks.SteamServer.GameTags = "mp300,cp200,ptrak,qp0,$reu1,v2590,^w,^v,^e,EU,born1750105939,gmrust,cs123128,^o^z",
#endif
                        additionalAttributes = "", ownerEmail = _config.OwnerEmail
                    }
                    );
                }
            }
            public static class Events {
                public static void Send(List<EventLogger.EventLog> eventLogs, Action<int, string> callback = null) {
                    try {
                        var content = JsonConvert.SerializeObject(eventLogs, EventLogger.EventLog.LogConverter);
                        SendPostRequest(GetRandomServerUrl(URL.GetCurrent(URL.Events)), content, content, callback);
                    }
                    catch {
                    }
                }
            }
            public static class Discord {
                public static void NotifyBannedConnection(Connection connection, bool bannedHwid, string mainSteamId = null) {
                    var message = new {
                        embeds = new object[] {
                            new {
                                title = "**Попытка зайти с баном**", description = $"* Сервер: **{ConVar.Server.hostname}**" + $"\n* SteamID: **{connection.userid}**" + $"\n* IP: **{TirifyGameExt.IPAddressWithoutPort(connection)}**" + $"\n* Забанен по железу: **{(bannedHwid ? "Да" : "Нет")}**" + (mainSteamId != null ? $"\n* Основной аккаунт: **{mainSteamId}**" : string.Empty), color = 13491712
                            }
                        }
                    }
                    ;
                    Singleton.webrequest.Enqueue(_config.BanSystem.DiscordWebhook, JsonConvert.SerializeObject(message), (code, response) => {
                        if (code >= 300 || response == null) {
                            Singleton.PrintWarning($"Не удалось отправить уведомление о забаненном ({code}): {response}");
                        }
                    }
                    , Singleton, Core.Libraries.RequestMethod.POST, new Dictionary<string, string>() {
                        {
                            "Content-Type", "application/json"
                        }
                    }
                    );
                }
            }
            private static void SendPostRequest(string url, string content, string signSalt, Action<int, string> callback = null, int mirrorIndex = -1) {
                if (mirrorIndex == -1) {
                    mirrorIndex = URL.CurrentServer;
                }
                var requestId = Guid.NewGuid().ToString();
                var sign = CreateMd5Hash(_config.ServerApiKey + requestId + signSalt);
                Singleton.NextTick(() => {
                    Singleton.webrequest.Enqueue(url, content, (code, response) => ValidateResponse(url, content, signSalt, code, response, callback, mirrorIndex), Singleton, Core.Libraries.RequestMethod.POST, new Dictionary<string, string>() {
                        {
                            "x-app-version", Singleton.Version.ToString()
                        }
                        , {
                            "x-app-requestid", requestId
                        }
                        , {
                            "x-app-name", Singleton.Name
                        }
                        , {
                            "x-app-sign", sign
                        }
                        , {
                            "x-app-serverkey", _config.ServerApiKey
                        }
                        , {
                            "x-app-token", _config.ServerToken
                        }
                        , {
                            "Content-Type", "application/json"
                        }
                        ,
                    }
                    , 6);
                }
                );
            }
            private static void ValidateResponse(string url, string content, string signSalt, int code, string response, Action<int, string> callback = null, int mirrorIndex = 0) {
#if STAGE
                Singleton.Puts($"{url} - {response} ({code})");
#endif
                if (code == 0 || code > 500) {
                    string serviceName = GetServiceName(url);
                    if (string.IsNullOrEmpty(serviceName)) {
                        return;
                    }
                    string mirrorUrl = URL.Get(serviceName, ++mirrorIndex);
                    // не осталось больше зеркал :(
                    if (string.IsNullOrEmpty(mirrorUrl)) {
                        return;
                    }
                    var lastUrl = URL.Get(serviceName, mirrorIndex - 1);
                    string queryString = url.Replace(lastUrl, "").Replace(lastUrl.Replace(".tirify.com", "-in-stage.tirify.com"), "");
                    string finalMirrorUrl = mirrorUrl + queryString;
                    //Singleton.Puts($"Failed to connect to our service, use mirror {mirrorIndex}");
                    SendPostRequest(finalMirrorUrl, content, signSalt, callback, mirrorIndex);
                    return;
                }
                if (code >= 200 && code < 300) {
                    URL.CurrentServer = mirrorIndex;
                }
                if (code >= 300) {
                    switch (code) {
                        case 401 : Singleton.RegisterServer();
                        break;
                        default : {
                            string serviceName = GetServiceName(url);
                            Singleton.RaiseError($"Request on service {serviceName} had a response with error code: {code}: {response}");
                            break;
                        }
                    }
                }
                if (callback != null) {
                    try {
                        callback(code, response);
                    }
                    catch (Exception ex) {
                        Singleton.RaiseError($"Error occured in webrequest callback: {ex.Message}");
                    }
                }
            }
            private static string GetServiceName(string serviceUrl) {
                foreach (var url in URL._urls) {
                    if (serviceUrl.Contains(url.Key)) {
                        return url.Key;
                    }
                }
                return string.Empty;
            }
        }
#endregion
#region [ Config ]
        public class Configuration {
            [JsonIgnore]
            public string ServerToken = string.Empty;
            [JsonProperty("Лицензионный ключ сервера")]
            public string ServerApiKey = GenerateRandomMD5();
            [JsonProperty("Электронная почта владельца")]
            public string OwnerEmail = string.Empty;
            [JsonProperty("Интервал отправки событий на сервер")]
            public int EventSendInterval = 10;
            [JsonProperty("Ссылка на группу VK")]
            public string UrlVk = string.Empty;
            [JsonProperty("Ссылка на магазин")]
            public string UrlShop = string.Empty;
            [JsonProperty("Ссылка на Discord")]
            public string UrlDiscord = string.Empty;
            [JsonProperty("Конфигурация бан системы")]
            public BanSystemConfiguration BanSystem = new BanSystemConfiguration();
        }
        public class BanSystemConfiguration {
            [JsonProperty("Показывать игроку причину бана")]
            public bool ShowBanReason {
                get;
                set;
            }
            = false;
            [JsonProperty("Автоматически банить по айпи игрока")]
            public bool AutoBanIp {
                get;
                set;
            }
            = true;
            [JsonProperty("Вебхук для уведомлений")]
            public string DiscordWebhook {
                get;
                set;
            }
            = string.Empty;
            [JsonProperty("Уведомлять в дискорд, если игрок с баном пытается зайти")]
            public bool NotifyBannedConnection {
                get;
                set;
            }
            = false;
        }
        internal static Configuration _config = new Configuration();
        public class Database {
            [JsonProperty("Список забаненных игроков")]
            public Dictionary<ulong, TirifyBanSystem.BannedUser> BannedUsers {
                get;
                set;
            }
            = new Dictionary<ulong, TirifyBanSystem.BannedUser>();
        }
        internal static Database _data = new Database();
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                _config = Config.ReadObject<Configuration>();
            }
            catch {
                LoadDefaultConfig();
            }
            SaveConfig();
            try {
                _data = Interface.Oxide.DataFileSystem.ReadObject<Database>(this.Name);
            }
            catch {
                _data = new Database();
            }
            SaveData();
        }
        protected override void LoadDefaultConfig() {
            _config = new Configuration();
        }
        protected override void SaveConfig() {
            Config.WriteObject(_config, true);
        }
        private void SaveData() {
            Interface.Oxide.DataFileSystem.WriteObject(this.Name, _data, true);
        }
#endregion
#region [ Plugin Hooks ]
        [HookMethod("IsPlayerNoSteam")]
        private bool IsPlayerTirifyLicense(string steamId) => (bool)(TGPP?.Call("IsPlayerNoSteam", steamId) ?? false);
        [HookMethod("GetNoSteamCount")]
        private int GetNoSteamCount() => (int)(TGPP?.Call("GetNoSteamCount") ?? 0);
        [HookMethod("IsSteam")]
        private bool IsSteam(Network.Connection connection) => (bool)(TGPP?.Call("IsSteam", connection) ?? false);
        [HookMethod("OnPrivateMessage")]
        private void OnPrivateMessage(string senderId, string targetId, string message) {
            BasePlayer sender = Player.FindById(senderId), target = Player.FindById(targetId);
            if (sender == null || target == null) {
                return;
            }
            EventLogger.LogChatMessage(sender, "pm", message, target);
        }
        [HookMethod("SetTirifyBan")]
        private void SetTirifyBan(string steamIdString, string reason = "") {
            ulong steamId = 0;
            if (ulong.TryParse(steamIdString, out steamId)) {
                TirifyBanSystem.BanPlayer(steamId, reason);
            }
        }
        [HookMethod("SetTirifyUnBan")]
        private void SetTirifyUnBan(string steamIdString, string reason = "") {
            ulong steamId = 0;
            if (ulong.TryParse(steamIdString, out steamId)) {
                TirifyBanSystem.UnbanPlayer(steamId);
            }
        }
        private string GetPlayerSessionID(BasePlayer player) => TirifyGameExt.GetSessionUID(player.Connection);
        private string GetServerRestartId() => this.GetRestartId().ToString();
        private string GetServerWipeId() => this.GetWipeId();
        private Dictionary<string, string> GetPlayerHwid(string steamId) => (Dictionary<string, string>)(TGPP?.Call("GetPlayerHwid", steamId) ?? new Dictionary<string, string>());
#endregion
#region [ Functions ]
        private void RegisterServer() {
            try {
                // update steam tags before sending it
                if (TirifyGameExt.UpdateServerInformationMethod != null) {
                    TirifyGameExt.UpdateServerInformationMethod.Invoke(ServerMgr.Instance, new object[0]);
                }
                // init
                API.Server.Init((Action<int, string>)((code, response) => {
                    var responseObject = JsonConvert.DeserializeObject<Dictionary<string, object>>((string)response);
                    if (responseObject == null) {
                        return;
                    }
                    if ((bool)responseObject["success"] == false) {
                        throw new Exception($"/server/init returned false");
                    }
                    _config.ServerApiKey = responseObject["serverKey"].ToString();
                    _config.ServerToken = responseObject["serverToken"].ToString();
                    SaveConfig();
                    SendTirifyLicenseP
// ... [Code preview truncated due to length. Full source in attached file] ...

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