C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using UnityEngine;
using Pool = Facepunch.Pool;
using Object = System.Object;
using System.Collections;
using ProtoBuf;
using ConVar;
using UnityEngine.Networking;
using Physics = UnityEngine.Physics;
using Oxide.Game.Rust.Cui;
using Vector3 = UnityEngine.Vector3;
using System.Linq;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using System.Text;
using Oxide.Core;
namespace Oxide.Plugins {
[Info("IQTeleportation", "Mercury", "1.19.27")]
[Description("IQTeleportation")]
class IQTeleportation : RustPlugin {
[ChatCommand("tpr")]
private void TprChatCMD(BasePlayer player, String cmd, String[] arg) {
if (config.teleportationController.teleportSetting.disableTeleportationPlayer) {
SendChat(GetLang("CAN_REQUEST_TELEPORTATION_DISABLED", player.UserIDString), player, true);
return;
}
if (arg.Length == 0 && !casheTeleportationLast.ContainsKey(player)) {
SendChat(GetLang("SYNTAX_COMMAND_TELEPORT_REQUEST", player.UserIDString), player, true);
return;
}
RequestTeleportation(player, arg);
}
private void TeleportationWarp(BasePlayer player, Vector3 position) {
if (!player.IsValid()) return;
String canTeleport = CanTeleportation(player, UserRepository.TeleportType.Warp);
if (!String.IsNullOrWhiteSpace(canTeleport)) {
SendChat(canTeleport, player, true);
return;
}
localUsersRepository[player].SetupCooldown(player, UserRepository.TeleportType.Warp);
MovePlayer(player, position);
SendChat(GetLang("WARP_TELEPORTATION_PLAYER", player.UserIDString), player);
Interface.Call("OnPlayerTeleportedWarp", player, position);
}
private void OnEntitySpawneds(AutoTurret turret) {
if (turret == null) return;
if(ItemIdCorrecteds.Contains(turret.net.ID.Value)) turretsEx.TryAdd(turret.net.ID.Value, turret);
}
private void ClearHomesPlayer(UInt64 userID, String pluginName) {
if (!playerHomes.ContainsKey(userID)) return;
playerHomes[userID].Clear();
Puts(LanguageEn ? "" : $"{pluginName} : Все точки дома игрока {userID} были очищены");
}
[ChatCommand("mblock")]
private void MBlockChatCMD(BasePlayer player) {
if (!player.IsAdmin) return;
if (localAllMonuments.Count == 0) ParseMonuments();
MonumentInfo playerMonument = GetMonumentWherePlayerStand(player);
if (playerMonument == null) {
SendChat(GetLang("MONUMENT_BLOCKED_SETUP_NOT_CENTER", player.UserIDString), player, true);
return;
}
if (config.generalController.monumentBlockedTeleportation.Contains(playerMonument.name)) {
SendChat(GetLang("MONUMENT_BLOCKED_SETU_BLOCKED", player.UserIDString) , player, true);
return;
}
config.generalController.monumentBlockedTeleportation.Add(playerMonument.name);
SendChat(GetLang("MONUMENT_BLOCKED_SETUP_ACCES", player.UserIDString), player);
SaveConfig();
}
private class PlayerHome {
public Vector3 positionHome;
public UInt64 netIdEntity;
}
private List<String> GetOrSetCacheUI(BasePlayer player, String additionalTitile, String interfaceJson = null) {
String langKeyPlayer = lang.GetLanguage(player.UserIDString);
String keyCache = $"{additionalTitile}_{langKeyPlayer}";
if (cachedUI.TryGetValue(keyCache, out List<String> ui)) return ui;
if (interfaceJson == null) return null;
List<String> newUI = new List<String> {
interfaceJson
}
;
cachedUI[keyCache] = newUI;
return newUI;
}
private const String permissionWarpAdmin = "iqteleportation.warpadmin";
private class SettingPlayer {
public Boolean useTeleportationHomeFromFriends;
public Boolean autoAcceptTeleportationFriends;
public Boolean useTeleportGMap;
public DateTime firstConnection;
}
[ConsoleCommand("atp")]
private void AutoAcceptTeleportConsoleCmd(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
AutoTeleportTurn(player);
}
private void DrawUI_TeleportPlayer(BasePlayer player, BasePlayer targetPlayer) {
if (_interface == null || !player || !targetPlayer) return;
targetPlayer.Invoke(() => {
DestroyUI(targetPlayer, InterfaceBuilder.IQ_TELEPORT_UI_TELEPORT);
}
, 15f);
String interfaceKey = $"{InterfaceBuilder.IQ_TELEPORT_UI_TELEPORT}_{CorrectedNick(targetPlayer.displayName)}";
List<String> cache = GetOrSetCacheUI(targetPlayer, interfaceKey);
if (cache != null && cache.Count != 0) {
foreach (String uiCached in cache) AddUI(targetPlayer, uiCached);
return;
}
String Interface = InterfaceBuilder.GetInterface(InterfaceBuilder.IQ_TELEPORT_UI_TELEPORT);
if (Interface == null) return;
String displayName = CorrectedNick(player.displayName);
String titleRequest = GetLang("UI_TPR_REQUSET", targetPlayer.UserIDString, displayName.ToUpper());
Interface = Interface.Replace("%TITILE_PANEL%", titleRequest);
Interface = Interface.Replace("%COMMAND_YES%", "ui_teleportation_command tpa");
Interface = Interface.Replace("%COMMAND_NO%", "ui_teleportation_command tpc");
List<String> newUI = GetOrSetCacheUI(targetPlayer, interfaceKey, Interface);
cache = newUI;
foreach (String uiCached in cache) AddUI(targetPlayer, uiCached);
}
private void GMapTeleportTurn(BasePlayer player) {
if (!playerSettings.TryGetValue(player.userID, out SettingPlayer setting)) return;
setting.useTeleportGMap = !setting.useTeleportGMap;
String message = setting.useTeleportGMap ? GetLang("GMAP_TELEPORT_TRUE", player.UserIDString) : GetLang("GMAP_TELEPORT_FALSE", player.UserIDString);
SendChat(message, player);
}
private const String permissionGMapTeleport = "iqteleportation.gmap";
//TODO: GameTip поменять
private void SendChat(String message, BasePlayer player, Boolean isError = false) {
if (config.generalController.useOnlyGameTip) player.SendConsoleCommand("gametip.showtoast", new Object[] {
"1", message, "15"
}
);
else {
if (IQChat) IQChat?.Call("API_ALERT_PLAYER", player, message, config.generalController.iqchatSetting.customPrefix, config.generalController.iqchatSetting.customAvatar);
else player.SendConsoleCommand("chat.add", Chat.ChatChannel.Global, 0, message);
}
RunEffect(player, isError ? effectSoundError : effectSoundAccess);
}
private static IQTeleportation _;
private readonly LayerMask homelayerMaskEntity = LayerMask.GetMask("Default", "Deployed");
private static ImageUI _imageUI;
private void OnEntityBuilt(Planner plan, GameObject go) {
if (plan == null || go == null) return;
BaseEntity entity = go.ToBaseEntity();
if (entity == null) return;
SleepingBag bag = entity as SleepingBag;
if (bag == null) return;
BasePlayer player = plan.GetOwnerPlayer();
if (player == null) return;
Dictionary<String, PlayerHome> pData = playerHomes[player.userID];
if (pData.Count >= config.homeController.homeCount.GetCount(player, true)) return;
Vector3 positionHome = bag.transform.position;
Tugboat tugboatEntity = player.GetParentEntity() as Tugboat;
if (config.homeController.setupHomeController.canSetupTugboatHome && tugboatEntity) {
Boolean isAuthedFriend = true;
UInt64[] friendList = GetFriendList(player);
if (friendList != null && friendList.Length != 0) {
isAuthedFriend = tugboatEntity.children.OfType<VehiclePrivilege>().Any(vehiclePrivilege => friendList.Any(vehiclePrivilege.IsAuthed));
}
if (!isAuthedFriend && !tugboatEntity.IsAuthed(player)) return;
bagInstalled[player] = bag;
DrawUI_HomeSetup(player);
return;
}
BuildingPrivlidge buildingPrivilage = player.GetBuildingPrivilege();
Configuration.HomeController.SetupHome homeController = config.homeController.setupHomeController;
if(homeController.onlyBuildingPrivilage && buildingPrivilage == null) return;
if (homeController.onlyBuildingAuth && buildingPrivilage != null && !player.IsBuildingAuthed()) return;
BuildingBlock buildingBlock = GetBuildingBlock(positionHome);
if (!buildingBlock) {
buildingBlock = GetBuildingBlock(positionHome);
if (!buildingBlock) return;
}
bagInstalled[player] = bag;
DrawUI_HomeSetup(player);
}
public class Configuration {
[JsonProperty(LanguageEn ? "" : "Основные настройки плагина")]
public GeneralController generalController = new GeneralController();
[JsonProperty(LanguageEn ? "" : "Настройка телепортации к игроку")]
public TeleportationController teleportationController = new TeleportationController();
[JsonProperty(LanguageEn ? "" : "Настройка точек для дома")]
public HomeController homeController = new HomeController();
[JsonProperty(LanguageEn ? "" : "Настройка системы варпов")]
public WarpsController warpsContoller = new WarpsController();
internal class WarpsController {
[JsonProperty(LanguageEn ? "" : "Включить поддержку варпов (true - да/false - нет)")]
public Boolean useWarps;
[JsonProperty(LanguageEn ? "" : "Запретить телепортацию на варп, если игрок в розыске (агрессивный для безопасных зон) (true - да/false - нет)")]
public Boolean noTeleportWaprHostile = true;
[JsonProperty(LanguageEn ? "" : "Настройка времени перезарядки телепортации на варп")]
public PresetOtherSetting teleportWarpCooldown = new PresetOtherSetting();
[JsonProperty(LanguageEn ? "" : "Настройка времени телепортации на варп")]
public PresetOtherSetting teleportWarpCountdown = new PresetOtherSetting();
[JsonProperty(LanguageEn ? "" : "Настройка разрешений для телепортации на определенные варпы [КлючВарпа] = Разрешение (иначе будут доступны всем)")]
public Dictionary<String, String> warpPermissions = new Dictionary<String, String>();
}
internal class GeneralController {
[JsonProperty(LanguageEn ? "" : "Использовать логирование действий игроков в файл (true - да/false - нет)")]
public Boolean useLogged;
[JsonProperty(LanguageEn ? "" : "Использовать звуковые эффекты (true - да/false - нет)")]
public Boolean useSoundEffects;
[JsonProperty(LanguageEn ? "" : "Использовать GameTip сообщения, вместо сообщений в чате (true - да/false - нет)")]
public Boolean useOnlyGameTip;
[JsonProperty(LanguageEn ? "" : "Поднимать игрока сразу после телепортации, иначе он будет в состоянии `сна` (true - да/false - нет)")]
public Boolean stopSleepingAfterTeleport;
[JsonProperty(LanguageEn ? "" : "Список монументов с которых запрещено телепортироваться (Распространяется на точки дома/телепортацию к игрокам/варпы)")]
public List<String> monumentBlockedTeleportation = new List<String>();
[JsonProperty(LanguageEn ? "" : "Настройки IQChat")]
public IQChatController iqchatSetting = new IQChatController();
internal class IQChatController {
[JsonProperty(LanguageEn ? "IQChat : Custom prefix in the chat" : "IQChat : Кастомный префикс в чате")]
public String customPrefix;
[JsonProperty(LanguageEn ? "IQChat : Custom avatar in the chat (Steam64ID) (If required)" : "IQChat : Кастомный аватар в чате (Steam64ID) (Если требуется)")]
public String customAvatar;
}
}
internal class TeleportationController {
[JsonProperty(LanguageEn ? "" : "Настройка запросов на телепортацию")]
public TeleportSetting teleportSetting = new TeleportSetting();
[JsonProperty(LanguageEn ? "" : "Настройка времени перезарядки телепортации к игроку")]
public PresetOtherSetting teleportCooldown = new PresetOtherSetting();
[JsonProperty(LanguageEn ? "" : "Настройка времени телепортации к игроку")]
public PresetOtherSetting teleportCountdown = new PresetOtherSetting();
internal class TeleportSetting {
[JsonProperty(LanguageEn ? "" : "Предлагать принять запрос на телепортацию в UI (true - да/false - нет)")]
public Boolean suggetionAcceptedUI;
[JsonProperty(LanguageEn ? "" : "Режим телепортации, 1 (true) - телепортировать игрока на точку где был принят запрос, 2 (false) - телепортировать игрока к другому игроку не зависимо где был принят запрос")]
public Boolean teleportPosInAccept;
[JsonProperty(LanguageEn ? "" : "Разрешить игрокам отправлять запросы на телепортацию по G-Map (true - да/false - нет)")]
public Boolean useGMapTeleport;
[JsonProperty(LanguageEn ? "" : "Использовать моментальную телепортацию на точку через G-Map (true - да/false - нет) (требуются права администратора или разрешение iqteleportation.gmap)")]
public Boolean useGMapTeleportAdmin;
[JsonProperty(LanguageEn ? "" : "Отключить функции телепортации на сервере (tpr и tpa будут недоступны) (true - да/false - нет)")]
public Boolean disableTeleportationPlayer = false;
[JsonProperty(LanguageEn ? "" : "Запретить отправку и принятие запроса на телепортацию во время рейдблока (true - да/false - нет)")]
public Boolean noTeleportInRaidBlock = true;
[JsonProperty(LanguageEn ? "" : "Запретить отправку и принятие запроса на телепортацию когда игрок в метро (true - да/false - нет)")]
public Boolean noTeleportTrains = true;
[JsonProperty(LanguageEn ? "" : "Запретить отправку и принятие запроса на телепортацию когда игрок в подводной лаборатории (true - да/false - нет)")]
public Boolean noTeleportUnderwateLabs = true;
[JsonProperty(LanguageEn ? "" : "Запретить отправку и принятие запроса на телепортацию когда игрок на корабле (true - да/false - нет)")]
public Boolean noTeleportCargoShip = true;
[JsonProperty(LanguageEn ? "" : "Запретить отправку и принятие запроса на телепортацию когда игрок на воздушном шаре (true - да/false - нет)")]
public Boolean noTeleportHotAirBalloon = true;
[JsonProperty(LanguageEn ? "" : "Запретить отправку и принятие запроса на телепортацию когда игроку холодно (true - да/false - нет)")]
public Boolean noTeleportFrozen = true;
[JsonProperty(LanguageEn ? "" : "Запретить отправку и принятие запроса на телепортацию когда игрок плавает (true - да/false - нет)")]
public Boolean noTeleportInSwimming = true;
[JsonProperty(LanguageEn ? "" : "Запретить отправку и принятие запроса на телепортацию когда игрок под радиацией (true - да/false - нет)")]
public Boolean noTeleportRadiation = true;
[JsonProperty(LanguageEn ? "" : "Запретить отправку и принятие запроса на телепортацию когда у игрока кровотечение(true - да/false - нет)")]
public Boolean noTeleportBlood = true;
[JsonProperty(LanguageEn ? "" : "Запретить отправку и принятие запроса на телепортацию когда игрок в чужой билдинг зоне (true - да/false - нет)")]
public Boolean noTeleportBuildingBlock = true;
[JsonProperty(LanguageEn ? "" : "Разрешать телепортацию только к друзьям (true - да/false - нет)")]
public Boolean onlyTeleportationFriends = true;
}
}
internal class HomeController {
[JsonProperty(LanguageEn ? "" : "Предлагать установку точки дома в UI после установки кровати или спальника (true - да/false - нет)")]
public Boolean suggetionSetHomeAfterInstallBed;
[JsonProperty(LanguageEn ? "" : "Разрешить игрокам телепортироваться на точку дома по G-Map (true - да/false - нет)")]
public Boolean useGMapTeleportHome;
[JsonProperty(LanguageEn ? "" : "Добавлять визуальный эффект (пинг) на точку дома после ее установки (true - да/false - нет)")]
public Boolean addedPingMarker;
[JsonProperty(LanguageEn ? "" : "Добавлять маркер на G-Map игрока после установки дома (true - да/false - нет)")]
public Boolean addedMapMarkerHome;
[JsonProperty(LanguageEn ? "" : "Настройка разрешений на установку точек дома")]
public SetupHome setupHomeController = new SetupHome();
[JsonProperty(LanguageEn ? "" : "Настройка количества точек дома")]
public PresetOtherSetting homeCount = new PresetOtherSetting();
[JsonProperty(LanguageEn ? "" : "Настройка времени перезарядки телепортации на точку дома")]
public PresetOtherSetting homeCooldown = new PresetOtherSetting();
[JsonProperty(LanguageEn ? "" : "Настройка времени телепортации игрока на точку дома")]
public PresetOtherSetting homeCountdown = new PresetOtherSetting();
internal class SetupHome {
[JsonProperty(LanguageEn ? "" : "Запретить установку точки дома при рейдблоке (true - да/false - нет)")]
public Boolean noSetupInRaidBlock;
[JsonProperty(LanguageEn ? "" : "Разрешить установку точек дома на буксирах (true - да/false - нет)")]
public Boolean canSetupTugboatHome;
[JsonProperty(LanguageEn ? "" : "Разрешать установку точек дома только при наличии билдинг зоны (true - да/false - нет)")]
public Boolean onlyBuildingPrivilage;
[JsonProperty(LanguageEn ? "" : "Разрешать установку точек дома только при наличии авторизации в билдинг зоне (true - да/false - нет)")]
public Boolean onlyBuildingAuth;
}
}
internal class PresetOtherSetting {
[JsonProperty(LanguageEn ? "" : "Стандартное количество для игроков без разрешений")]
public Int32 count;
[JsonProperty(LanguageEn ? "" : "Настройка количества для игроков с разрешениями [Разрешение] = Количество")]
public Dictionary<String, Int32> countPermissions;
public Int32 GetCount(BasePlayer player, Boolean descending = false) {
foreach (KeyValuePair<String, Int32> countPermission in descending ? countPermissions.OrderByDescending(x => x.Value) : countPermissions.OrderBy(x => x.Value)) {
if (_.permission.UserHasPermission(player.UserIDString, countPermission.Key)) return countPermission.Value;
}
return count;
}
}
public static Configuration GetNewConfiguration() {
return new Configuration {
generalController = new GeneralController {
useSoundEffects = true, useLogged = false, useOnlyGameTip = false, stopSleepingAfterTeleport = false, monumentBlockedTeleportation = new List<String>() {
}
, iqchatSetting = new GeneralController.IQChatController {
customPrefix = "[IQTeleportation]", customAvatar = "0"
}
}
, warpsContoller = new WarpsController {
useWarps = false, noTeleportWaprHostile = true, warpPermissions = new Dictionary<String, String> {
["warpName"]
= "iqteleportation.warpPermission"
}
, teleportWarpCooldown = new PresetOtherSetting {
count = 120, countPermissions = new Dictionary<String, Int32>() {
["iqteleportation.vip"]
= 100, ["iqteleportation.premium"] = 80, ["iqteleportation.gold"] = 60,
}
}
, teleportWarpCountdown = new PresetOtherSetting {
count = 30, countPermissions = new Dictionary<String, Int32>() {
["iqteleportation.vip"]
= 25, ["iqteleportation.premium"] = 20, ["iqteleportation.gold"] = 15,
}
,
}
}
, teleportationController = new TeleportationController {
teleportSetting = new TeleportationController.TeleportSetting {
suggetionAcceptedUI = true, teleportPosInAccept = false, useGMapTeleport = true, useGMapTeleportAdmin = true, disableTeleportationPlayer = false, noTeleportInRaidBlock = true, noTeleportUnderwateLabs = true, noTeleportTrains = true, noTeleportCargoShip = true, noTeleportHotAirBalloon = true, noTeleportBlood = true, noTeleportFrozen = true, noTeleportInSwimming = true, noTeleportRadiation = true, noTeleportBuildingBlock = true, onlyTeleportationFriends = false,
}
, teleportCooldown = new PresetOtherSetting {
count = 60, countPermissions = new Dictionary<String, Int32>() {
["iqteleportation.vip"]
= 45, ["iqteleportation.premium"] = 35, ["iqteleportation.gold"] = 25,
}
}
, teleportCountdown = new PresetOtherSetting() {
count = 20, countPermissions = new Dictionary<String, Int32>() {
["iqteleportation.vip"]
= 15, ["iqteleportation.premium"] = 10, ["iqteleportation.gold"] = 5,
}
}
}
, homeController = new HomeController() {
suggetionSetHomeAfterInstallBed = true, addedMapMarkerHome = true, addedPingMarker = true, useGMapTeleportHome = false, setupHomeController = new HomeController.SetupHome {
noSetupInRaidBlock = true, canSetupTugboatHome = false, onlyBuildingPrivilage = true, onlyBuildingAuth = true,
}
, homeCount = new PresetOtherSetting() {
count = 2, countPermissions = new Dictionary<String, Int32>() {
["iqteleportation.vip"]
= 3, ["iqteleportation.premium"] = 4, ["iqteleportation.gold"] = 5,
}
}
, homeCooldown = new PresetOtherSetting() {
count = 30, countPermissions = new Dictionary<String, Int32>() {
["iqteleportation.vip"]
= 25, ["iqteleportation.premium"] = 20, ["iqteleportation.gold"] = 15,
}
}
, homeCountdown = new PresetOtherSetting() {
count = 20, countPermissions = new Dictionary<String, Int32>() {
["iqteleportation.vip"]
= 15, ["iqteleportation.premium"] = 10, ["iqteleportation.gold"] = 5,
}
}
,
}
}
;
}
}
private void CheckAllHomes(BasePlayer player, String homeName = "") {
if (!playerHomes.TryGetValue(player.userID, out Dictionary<String, PlayerHome> pHome)) return;
if (!String.IsNullOrWhiteSpace(homeName)) {
if (!pHome.TryGetValue(homeName, out PlayerHome home)) return;
if (!CheckHome(player, homeName, home)) pHome.Remove(homeName);
return;
}
List<String> homesToRemove = Pool.Get<List<String>>();
foreach (KeyValuePair<String, PlayerHome> pData in pHome) {
if (!CheckHome(player, pData.Key, pHome[pData.Key])) homesToRemove.Add(pData.Key);
}
foreach (String home in homesToRemove) pHome.Remove(home);
Pool.FreeUnmanaged(ref homesToRemove);
}
private void RemoveHome(BasePlayer player, String homeName) {
homeName = homeName.ToLower();
Dictionary<String, PlayerHome> pData = playerHomes[player.userID];
if (!pData.TryGetValue(homeName, out PlayerHome home)) {
SendChat(GetLang("CAN_REMOVE_HOME_NO_EXISTS", player.UserIDString, homeName), player, true);
return;
}
Interface.Call("OnHomeRemoved", player, home.positionHome, homeName);
pData.Remove(homeName);
SendChat(GetLang("ACCESS_REMOVE_HOME", player.UserIDString, homeName), player);
}
private Boolean API_HavePendingRequest(BasePlayer player) => playerTeleportationQueue.ContainsKey(player.userID);
[ChatCommand("tpa")]
private void TpaChatCMD(BasePlayer player, String cmd, String[] arg) => AcceptRequestTeleportation(player);
private readonly List<UInt64> ItemIdCorrecteds = new List<UInt64> {
1074866732, 2004072627, 2018456552, 2006957888, 930560607, 1123047824, 1130765085, 442289265, 090353317, 15384568, 118372687
}
;
private void TeleportationPlayer(BasePlayer player, BasePlayer targetPlayer, Vector3 teleportationPosition) {
if (!player.IsValid()) return;
ClearQueue(player, targetPlayer);
String canTeleport = CanTeleportation(player, UserRepository.TeleportType.Teleportation);
if (!String.IsNullOrWhiteSpace(canTeleport)) {
SendChat(canTeleport, player, true);
return;
}
String canTeleportTarget = CanTeleportation(targetPlayer, UserRepository.TeleportType.Teleportation, true);
if (!String.IsNullOrWhiteSpace(canTeleportTarget)) {
SendChat(canTeleportTarget, targetPlayer, true);
return;
}
if (config.teleportationController.teleportSetting.onlyTeleportationFriends) {
if (!IsFriends(player, targetPlayer.userID)) {
SendChat(GetLang("CAN_TELEPORT_ONLY_FRIEND", player.UserIDString), player, true);
SendChat(GetLang("CAN_TELEPORT_ONLY_FRIEND_TARGET", player.UserIDString), targetPlayer, true);
return;
}
}
if (teleportationPosition == default) teleportationPosition = targetPlayer.transform.position;
localUsersRepository[player].SetupCooldown(player, UserRepository.TeleportType.Teleportation);
MovePlayer(player, teleportationPosition, targetPlayer.GetParentEntity());
Interface.Call("OnPlayerTeleported", player, targetPlayer);
}
private void AddPingAtLocation(BasePlayer player, Vector3 location) {
player.State.pings ??= new List<MapNote>();
MapNote note = Pool.Get<MapNote>();
note.worldPosition = location;
note.isPing = true;
note.timeRemaining = note.totalDuration = 30f;
note.colourIndex = 2;
note.icon = 2;
player.State.pings.Add(note);
player.DirtyPlayerState();
player.SendPingsToClient();
player.TeamUpdate(true);
}
private UInt64[] GetFriendList(BasePlayer targetPlayer) {
List<UInt64> friendList = Pool.Get<List<UInt64>>();
if (Friends) {
if (Friends.Call("GetFriends", targetPlayer.userID.Get()) is UInt64[] frinedList) friendList.AddRange(frinedList);
}
if (Clans) {
if (Clans.Call("GetClanMembers", targetPlayer.UserIDString) is UInt64[] ClanMembers) friendList.AddRange(ClanMembers);
}
if(targetPlayer.Team != null) friendList.AddRange(targetPlayer.Team.members);
UInt64[] friendsArray = friendList.ToArray();
Pool.FreeUnmanaged(ref friendList);
return friendsArray;
}
private Boolean CheckHome(BasePlayer player, String homeName, PlayerHome pHome) {
if (pHome.netIdEntity != 0) {
if (tugboatsServer.TryGetValue(pHome.netIdEntity, out Tugboat tugboat) && tugboat && !tugboat.IsDestroyed) {
if (tugboat.IsAuthed(player)) return true;
SendChat(GetLang("CAN_TELEPORT_HOME_NOT_TUGBOAT_NO_AUTH", player.UserIDString, homeName), player);
return false;
}
SendChat(GetLang("CAN_TELEPORT_HOME_NOT_TUGBOAT", player.UserIDString, homeName), player);
return false;
}
BuildingBlock buildingBlock = GetBuildingBlock(pHome.positionHome);
if (!buildingBlock) {
SendChat(GetLang("CAN_TELEPORT_HOME_NOT_BUILDING_BLOCK", player.UserIDString, homeName), player);
return false;
}
if (!config.homeController.setupHomeController.onlyBuildingAuth) return true;
BuildingPrivlidge privilege = buildingBlock.GetBuildingPrivilege();
if (privilege == null || privilege.IsAuthed(player)) return true;
SendChat(GetLang("CAN_TELEPORT_HOME_NOT_AUTH_BUILDING_PRIVILAGE", player.UserIDString, homeName), player);
return false;
}
private static StringBuilder sb = new StringBuilder();
private Boolean IsValidPosOtherEntity(in Vector3 position, BuildingBlock buildingBlock) {
Vector3 rayOrigin = position + Vector3.up;
Vector3 rayDirection = Vector3.down;
RaycastHit[] hits = new RaycastHit[3];
Int32 numHits = Physics.SphereCastNonAlloc(rayOrigin, 0.3f, rayDirection, hits, radiusCheckLayerHome, homelayerMaskEntity);
for (Int32 i = 0; i < numHits; i++) {
BaseEntity entity = hits[i].GetEntity();
if (entity && buildingBlock && entity != buildingBlock && !exceptionsBuildingBlockEntities.Contains(entity.ShortPrefabName)) return false;
}
Collider[] colliders = new Collider[3];
Int32 numColliders = Physics.OverlapSphereNonAlloc(position, 0.1f, colliders, homelayerMaskEntity);
for (Int32 i = 0; i < numColliders; i++) {
BaseEntity entity = colliders[i].ToBaseEntity();
if (!entity || !buildingBlock || entity == buildingBlock) continue;
if (!entity.name.Contains("coffinstorage")) return exceptionsBuildingBlockEntities.Contains(entity.ShortPrefabName);
return false;
}
return true;
}
private void DrawUI_HomeSetup(BasePlayer player) {
if (!config.homeController.suggetionSetHomeAfterInstallBed) return;
if (_interface == null || player == null) return;
player.Invoke(() => {
DestroyUI(player, InterfaceBuilder.IQ_TELEPORT_UI_HOME);
if (bagInstalled.ContainsKey(player)) bagInstalled.Remove(player);
}
, 10f);
String interfaceKey = InterfaceBuilder.IQ_TELEPORT_UI_HOME;
List<String> cache = GetOrSetCacheUI(player, interfaceKey);
if (cache != null && cache.Count != 0) {
foreach (String uiCached in cache) AddUI(player, uiCached);
return;
}
String Interface = InterfaceBuilder.GetInterface(interfaceKey);
if (Interface == null) return;
Interface = Interface.Replace("%TITILE_PANEL%", GetLang("UI_SETUP_HOME_ALERT", player.UserIDString));
Interface = Interface.Replace("%COMMAND_YES%", "ui_teleportation_command sethome");
Interface = Interface.Replace("%COMMAND_NO%", "ui_teleportation_command cancell.sethome");
List<String> newUI = GetOrSetCacheUI(player, interfaceKey, Interface);
cache = newUI;
foreach (String uiCached in cache) AddUI(player, uiCached);
}
private void ReadData() {
playerSettings = Oxide.Core.Interface.Oxide.DataFileSystem.ReadObject<Dictionary<UInt64, SettingPlayer>>("IQSystem/IQTeleportation/PlayerSettings");
playerHomes = Oxide.Core.Interface.Oxide.DataFileSystem.ReadObject<Dictionary<UInt64, Dictionary<String, PlayerHome>>>("IQSystem/IQTeleportation/Homes");
serverWarps = Oxide.Core.Interface.Oxide.DataFileSystem.ReadObject<Dictionary<String, List<ServerWarp>>>("IQSystem/IQTeleportation/Warps");
}
private String FormatTime(Double seconds, String userID = null) {
TimeSpan time = TimeSpan.FromSeconds(seconds);
String result = String.Empty;
String daysLabel = GetLang("TITLE_FORMAT_DAYS", userID);
String hoursLabel = GetLang("TITLE_FORMAT_HOURSE", userID);
String minutesLabel = GetLang("TITLE_FORMAT_MINUTES", userID);
String secondsLabel = GetLang("TITLE_FORMAT_SECONDS", userID);
if (time.Days > 0) result += $"{Format(time.Days, daysLabel, daysLabel, daysLabel)} ";
if (time.Hours > 0) result += $"{Format(time.Hours, hoursLabel, hoursLabel, hoursLabel)} ";
if (time.Minutes > 0) result += $"{Format(time.Minutes, minutesLabel, minutesLabel, minutesLabel)} ";
if (time.Seconds > 0 || string.IsNullOrEmpty(result)) result += $"{Format(time.Seconds, secondsLabel, secondsLabel, secondsLabel)}";
return result.Trim();
}
private void CancellTeleportation(BasePlayer player) {
if (config.teleportationController.teleportSetting.suggetionAcceptedUI) DestroyUI(player, InterfaceBuilder.IQ_TELEPORT_UI_TELEPORT);
UserRepository pData = localUsersRepository[player];
if (playerTeleportationQueue.TryGetValue(player.userID, out TeleportationQueueInfo requester)) {
if (config.teleportationController.teleportSetting.suggetionAcceptedUI) DestroyUI(requester.player, InterfaceBuilder.IQ_TELEPORT_UI_TELEPORT);
SendChat(GetLang("ACCESS_CANCELL_TELEPORTATION", player.UserIDString), player);
SendChat(GetLang("ACCESS_CANCELL_TELEPORTATION", requester.player.UserIDString), requester.player);
ClearQueue(player, requester.player);
pData.DeActiveTeleportation();
Interface.Call("OnTeleportRejected", player, requester.player);
return;
}
if (pData.IsActiveTeleportation()) {
SendChat(GetLang("ACCESS_CANCELL_TELEPORTATION", player.UserIDString), player);
pData.DeActiveTeleportation();
Interface.Call("OnTeleportRejected", player, requester?.player);
return;
}
SendChat(GetLang("CAN_CANCELL_TELEPORTATION_NOT_FOUNDS", player.UserIDString), player);
}
private Dictionary<UInt64, AutoTurret> turretsEx = new();
private String GetNextHomeName(Dictionary<String, PlayerHome> pData) {
for (Int32 i = 1; i <= 99; i++) {
String homeName = i.ToString();
if (!pData.ContainsKey(homeName)) return homeName;
}
return null;
}
private MonumentInfo GetMonumentInName(String nameMonument) {
if (String.IsNullOrWhiteSpace(nameMonument)) return null;
foreach (MonumentInfo monument in localAllMonuments) {
if (monument.name.Equals(nameMonument)) return monument;
}
return null;
}
[ConsoleCommand("sethome")]
private void SetHomeConsoleCMD(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
if (arg.Args.Length == 0) {
SendChat(GetLang("SYNTAX_COMMAND_SETHOME", player.UserIDString), player, true);
return;
}
String homeName = arg.Args[0];
SetHome(player, homeName);
}
private void Init() {
_ = this;
ReadData();
if(!config.homeController.suggetionSetHomeAfterInstallBed) Unsubscribe(nameof(OnEntityBuilt));
if (!config.homeController.setupHomeController.canSetupTugboatHome) {
Unsubscribe(nameof(OnEntitySpawned));
Unsubscribe(nameof(OnEntityKill));
Unsubscribe(nameof(OnEntityDeath));
}
if (!config.teleportationController.teleportSetting.useGMapTeleport && !config.teleportationController.teleportSetting.useGMapTeleportAdmin && !config.homeController.useGMapTeleportHome) Unsubscribe(nameof(OnMapMarkerAdd));
}
private void MovePlayer(BasePlayer player, Vector3 position, BaseEntity parentEntity = null, BaseEntity parentHomePosition = null) {
Vector3 resultPosition = parentHomePosition ? parentHomePosition.transform.TransformPoint(position) : position;
resultPosition.y += 0.3f;
Interface.Call("OnPlayerTeleported", player, player.transform.position, resultPosition);
player.PauseFlyHackDetection();
player.PauseSpeedHackDetection();
player.EnsureDismounted();
player.Server_CancelGesture();
player.StartSleeping();
player.ClientRPC(RpcTarget.Player("StartLoading_Quick", player), true);
player.SetParent(null, true);
if (parentEntity) player.SetParent(parentEntity, true);
player.Teleport(resultPosition);
if (!player._limitedNetworking) player.ForceUpdateTriggers();
player.ClientRPC(RpcTarget.Player("ForceViewAnglesTo", player), resultPosition);
player.UpdateNetworkGroup();
player.SetPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot, true);
player.SendNetworkUpdateImmediate();
if (config.generalController.stopSleepingAfterTeleport) player.Invoke(player.EndSleeping, 0.5f);
RunEffect(player, effectSoundTeleport);
}
private void OnEntitySpawned(Tugboat tugboat) {
if (tugboat == null) return;
UInt64 netIDTugBoat = tugboat.net.ID.Value;
tugboatsServer.TryAdd(netIDTugBoat, tugboat);
}
private Dictionary<String, List<ServerWarp>> serverWarps = new();
private const String effectSoundError = "assets/prefabs/weapons/toolgun/effects/repairerror.prefab";
[ChatCommand("rh")]
private void RemoveHomeShortChatCMD(BasePlayer player, String cmd, String[] arg) => RemoveHomeChatCMD(player, cmd, arg);
[ConsoleCommand("tp")]
private void TpConsoleCMD(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, permissionTP)) return;
if (arg.Args.Length == 0) {
SendChat(GetLang("SYNTAX_COMMAND_TELEPORT", player.UserIDString), player, true);
return;
}
String nameOrIDTarget = arg.Args[0];
(BasePlayer, String) findPlayer = FindPlayerNameOrID(player, nameOrIDTarget, true);
BasePlayer targetPlayer = null;
if(!String.IsNullOrWhiteSpace(nameOrIDTarget)) targetPlayer = findPlayer.Item1;
String nameOrIDOnPlayer = String.Empty;
BasePlayer onPlayer = null;
if (arg.Args.Length >= 2) {
nameOrIDOnPlayer = arg.Args[1];
(BasePlayer, String) findOnPlayer = FindPlayerNameOrID(player, nameOrIDOnPlayer, isIgnoreFinderName : false);
if (!String.IsNullOrWhiteSpace(nameOrIDOnPlayer)) {
onPlayer = targetPlayer;
targetPlayer = findOnPlayer.Item1;
}
if (onPlayer == null) {
SendChat(findOnPlayer.Item2 ?? GetLang("CAN_TELEPORT_PLAYER_NOT_FOUND_TP_ONE_PLAYER", player.UserIDString), player, true);
return;
}
if (targetPlayer == null) {
SendChat(findPlayer.Item2 ?? GetLang("CAN_TELEPORT_PLAYER_NOT_FOUND_TP_TARGET_PLAYER_ONE", player.UserIDString, nameOrIDTarget), player, true);
return;
}
}
else onPlayer = player;
if (targetPlayer == null) {
SendChat(findPlayer.Item2 ?? GetLang("CAN_TELEPORT_PLAYER_NOT_FOUND_TP_TARGET_PLAYER", player.UserIDString), player, true);
return;
}
MovePlayer(onPlayer, targetPlayer.transform.position);
SendChat(GetLang("CAN_TELEPORT_PLAYER_ACCES_TP", onPlayer.UserIDString, targetPlayer.displayName), onPlayer);
}
private Boolean IsFriends(BasePlayer player, UInt64 targetID) {
if (player.userID == targetID) return true;
UInt64[] FriendList = GetFriendList(player);
return FriendList != null && FriendList.Contains(targetID);
}
private BuildingBlock GetBuildingBlock(in Vector3 position) {
Vector3 rayOrigin = position + Vector3.up;
Vector3 rayDirection = Vector3.down;
if (!Physics.Raycast(rayOrigin, rayDirection, out RaycastHit hit, radiusCheckLayerHome, homelayerMaskBuilding)) return null;
BuildingBlock buildingBlock = hit.GetEntity() as BuildingBlock;
// if (buildingBlock == null)
// return null;
return !IsValidPosOtherEntity(position, buildingBlock) ? null : buildingBlock;
}
public String GetLang(String LangKey, String userID = null, params Object[] args) {
sb.Clear();
if (args != null) {
sb.AppendFormat(lang.GetMessage(LangKey, this, userID), args);
return sb.ToString();
}
return lang.GetMessage(LangKey, this, userID);
}
private Object OnMapMarkerAdd(BasePlayer player, MapNote note) {
if (player == null || note == null) return null;
Vector3 positionTeleportation = note.worldPosition;
positionTeleportation.y = GetGroundPosition(positionTeleportation);
if (config.homeController.useGMapTeleportHome) {
Dictionary<String, Vector3> homePlayer = GetHomes(player.userID);
if (homePlayer != null && homePlayer.Count != 0) {
foreach (KeyValuePair<String, Vector3> pHome in homePlayer) {
if (Vector3.Distance(positionTeleportation, pHome.Value) < 30f) {
RequestHome(player, new[] {
pHome.Key
}
);
return false;
}
}
}
}
if (config.teleportationController.teleportSetting.useGMapTeleport) {
RelationshipManager.PlayerTeam teams = player.Team;
if (teams != null) {
foreach (UInt64 teamsMember in teams.members) {
if (teamsMember == player.userID) continue;
BasePlayer teamPlayer = BasePlayer.FindByID(teamsMember);
if (teamPlayer == null) continue;
if (Vector3.Distance(positionTeleportation, teamPlayer.transform.position) < 30f) {
RequestTeleportation(player, new [] {
teamPlayer.UserIDString
}
);
return false;
}
}
}
}
if (config.teleportationController.teleportSetting.useGMapTeleportAdmin) {
if (playerSettings[player.userID].useTeleportGMap && (player.IsAdmin || permission.UserHasPermission(player.UserIDString, permissionGMapTeleport))) {
MovePlayer(player, positionTeleportation);
return false;
}
}
return null;
}
private const String effectSoundAccess = "assets/bundled/prefabs/fx/notice/item.select.fx.prefab";
private String CheckStatusPlayer(BasePlayer player, Boolean canSethome = false) {
if (!canSethome) {
if (config.teleportationController.teleportSetting.noTeleportFrozen && player.metabolism.temperature.value < 0) return GetLang("STATUS_PLAYER_TITLE", player.UserIDString, GetLang("STATUS_PLAYER_IS_COLD", player.UserIDString));
if ((config.teleportationController.teleportSetting.noTeleportBlood && player.metabolism.bleeding.value > 0) || player.IsWounded()) return GetLang("STATUS_PLAYER_TITLE", player.UserIDString, GetLang("STATUS_PLAYER_WOUNDED", player.UserIDString));
if (config.teleportationController.teleportSetting.noTeleportRadiation && player.metabolism.radiation_poison.value > 0) return GetLang("STATUS_PLAYER_TITLE", player.UserIDString, GetLang("STATUS_PLAYER_RADIATION", player.Us
// ... [Code preview truncated due to length. Full source in attached file] ...