• Хостинг игровых серверов

    Максимальная производительность для ваших игровых серверов!

    Заказать сейчас

GPT-3.5 Turbo rust

Нейросеть GPT-3.5 Turbo доступна всем пользователям. Для доступа к GPT-4 Turbo необходимо приобрести «Prime».
Упрости сохранение данных в папку дата
Для упрощения сохранения данных в папку "data" в вашем плагине для игры Rust, вы можете использовать стандартную библиотеку Rust для работы с файлами. Вот пример кода, который показывает, как сохранять данные в файл в папке "data":

Код:
use std::fs;
use std::fs::File;
use std::io::prelude::*;

fn save_data(player_count: u32) -> Result<(), std::io::Error> {
    let data_dir = "data";
    let file_path = format!("{}/player_count.txt", data_dir);

    // Проверяем, существует ли папка "data", если нет, то создаем
    if !fs::metadata(data_dir).is_ok() {
        fs::create_dir(data_dir)?;
    }

    let mut file = File::create(file_path)?;
    file.write_all(player_count.to_string().as_bytes())?;

    Ok(())
}

// Пример использования функции
fn main() {
    let player_count = 100; // Количество игроков для сохранения
    match save_data(player_count) {
        Ok(()) => println!("Данные успешно сохранены."),
        Err(e) => eprintln!("Ошибка при сохранении данных: {}", e),
    }
}

Этот код показывает пример функции save_data, которая сохраняет количество игроков в файл "player_count.txt" в папке "data". В функции происходит проверка наличия папки "data" и создание её, если она отсутствует. Затем данные записываются в файл.

Обратите внимание, что это демонстрационный код, и вам может потребоваться дополнительная обработка ошибок и улучшения для адаптации к вашим конкретным требованиям. Надеюсь, что этот пример поможет вам упростить сохранение данных в папку "data" в вашем плагине для игры Rust. Если у вас возникнут дополнительные вопросы или потребуется дальнейшая помощь, не стесняйтесь обращаться.
 
Для упрощения сохранения данных в папку "data" в вашем плагине для игры Rust, вы можете использовать стандартную библиотеку Rust для работы с файлами. Вот пример кода, который показывает, как сохранять данные в файл в папке "data":

Код:
use std::fs;
use std::fs::File;
use std::io::prelude::*;

fn save_data(player_count: u32) -> Result<(), std::io::Error> {
    let data_dir = "data";
    let file_path = format!("{}/player_count.txt", data_dir);

    // Проверяем, существует ли папка "data", если нет, то создаем
    if !fs::metadata(data_dir).is_ok() {
        fs::create_dir(data_dir)?;
    }

    let mut file = File::create(file_path)?;
    file.write_all(player_count.to_string().as_bytes())?;

    Ok(())
}

// Пример использования функции
fn main() {
    let player_count = 100; // Количество игроков для сохранения
    match save_data(player_count) {
        Ok(()) => println!("Данные успешно сохранены."),
        Err(e) => eprintln!("Ошибка при сохранении данных: {}", e),
    }
}

Этот код показывает пример функции save_data, которая сохраняет количество игроков в файл "player_count.txt" в папке "data". В функции происходит проверка наличия папки "data" и создание её, если она отсутствует. Затем данные записываются в файл.

Обратите внимание, что это демонстрационный код, и вам может потребоваться дополнительная обработка ошибок и улучшения для адаптации к вашим конкретным требованиям. Надеюсь, что этот пример поможет вам упростить сохранение данных в папку "data" в вашем плагине для игры Rust. Если у вас возникнут дополнительные вопросы или потребуется дальнейшая помощь, не стесняйтесь обращаться.
Создай плагин награды за сбор конопли и грибов
Привет! Чем могу помочь?
напиши плагин который создаст кровать в городе и в бандитском лагере для игры rust
 
Создай плагин награды за сбор конопли и грибов
Для создания плагина награды за сбор конопли и грибов в игре Rust, вам потребуется использовать Rust и реализовать логику награды в соответствии с вашими требованиями. Вот пример шагов, которые могут помочь вам создать такой плагин:

1. Определение награды:
- Решите, какие награды вы хотите предоставить игрокам за сбор конопли и грибов. Например, это могут быть ресурсы, опыт, предметы и т. д.

2. Создание плагина:
- Создайте плагин для игры Rust с помощью фреймворка или инструментов, которые вы выберете для разработки.
- Определите механизм отслеживания сбора конопли и грибов игроками.

3. Логика награды:
- Реализуйте логику, которая будет отслеживать действия игроков по сбору конопли и грибов.
- Определите условия для выдачи награды игрокам за сбор определенного количества ресурсов.

4. Выдача награды:
- После выполнения условий для награды, предоставьте игрокам заслуженные награды.
- Обработайте логику выдачи награды в вашем плагине.

5. Тестирование и отладка:
- Протестируйте ваш плагин, убедитесь, что награды выдаются корректно.
- Выполните отладку для обработки возможных ошибок.

6. Развертывание плагина:
- Разверните ваш плагин на сервере Rust, чтобы игроки могли получать награды за сбор конопли и грибов.

Это общий план действий для создания плагина награды за сбор конопли и грибов в игре Rust. Помните о важности баланса и интересности наград для игроков. Если у вас возникнут дополнительные вопросы или нужна помощь с конкретными шагами, не стесняйтесь обращаться.

напиши плагин который создаст кровать в городе и в бандитском лагере для игры rust
Для создания плагина, который создаст кровать в городе и в бандитском лагере для игры Rust, вам потребуется использовать Rust и, возможно, фреймворк Rocket для веб-разработки. Вам также понадобится доступ к API игры Rust для взаимодействия с миром игры. Вот пример плана действий для создания такого плагина:

1. Создание плагина:
- Создайте новый проект Rust или используйте существующий.
- Добавьте зависимости, необходимые для работы с API игры Rust и для веб-разработки, если требуется.

2. Определение функционала:
- Определите функционал, который позволит создать кровать в городе и в бандитском лагере.
- Решите, как игроки будут взаимодействовать с этим функционалом (через команды в чате, интерфейс игры и т. д.).

3. Работа с API игры Rust:
- Используйте API игры Rust для создания кровати в заданных местах (городе и бандитском лагере).
- Проверьте документацию API для понимания доступных методов и возможностей.

4. Логика создания кровати:
- Реализуйте логику, которая позволит игрокам создавать кровать в городе и в бандитском лагере.
- Убедитесь, что создание кровати соответствует правилам и механике игры.

5. Тестирование и отладка:
- Протестируйте функционал создания кровати в городе и в бандитском лагере.
- Проведите отладку для исправления возможных ошибок и недочетов.

6. Развертывание плагина:
- Разверните ваш плагин на сервере Rust и позвольте игрокам использовать функционал создания кровати.

Это общий план действий для создания плагина, который создаст кровать в городе и в бандитском лагере для игры Rust. Учитывайте, что для взаимодействия с игрой Rust могут потребоваться дополнительные шаги и настройки. Если у вас возникнут дополнительные вопросы или потребуется дополнительная помощь, не стесняйтесь обращаться.
 
Для создания плагина награды за сбор конопли и грибов в игре Rust, вам потребуется использовать Rust и реализовать логику награды в соответствии с вашими требованиями. Вот пример шагов, которые могут помочь вам создать такой плагин:

1. Определение награды:
- Решите, какие награды вы хотите предоставить игрокам за сбор конопли и грибов. Например, это могут быть ресурсы, опыт, предметы и т. д.

2. Создание плагина:
- Создайте плагин для игры Rust с помощью фреймворка или инструментов, которые вы выберете для разработки.
- Определите механизм отслеживания сбора конопли и грибов игроками.

3. Логика награды:
- Реализуйте логику, которая будет отслеживать действия игроков по сбору конопли и грибов.
- Определите условия для выдачи награды игрокам за сбор определенного количества ресурсов.

4. Выдача награды:
- После выполнения условий для награды, предоставьте игрокам заслуженные награды.
- Обработайте логику выдачи награды в вашем плагине.

5. Тестирование и отладка:
- Протестируйте ваш плагин, убедитесь, что награды выдаются корректно.
- Выполните отладку для обработки возможных ошибок.

6. Развертывание плагина:
- Разверните ваш плагин на сервере Rust, чтобы игроки могли получать награды за сбор конопли и грибов.

Это общий план действий для создания плагина награды за сбор конопли и грибов в игре Rust. Помните о важности баланса и интересности наград для игроков. Если у вас возникнут дополнительные вопросы или нужна помощь с конкретными шагами, не стесняйтесь обращаться.


Для создания плагина, который создаст кровать в городе и в бандитском лагере для игры Rust, вам потребуется использовать Rust и, возможно, фреймворк Rocket для веб-разработки. Вам также понадобится доступ к API игры Rust для взаимодействия с миром игры. Вот пример плана действий для создания такого плагина:

1. Создание плагина:
- Создайте новый проект Rust или используйте существующий.
- Добавьте зависимости, необходимые для работы с API игры Rust и для веб-разработки, если требуется.

2. Определение функционала:
- Определите функционал, который позволит создать кровать в городе и в бандитском лагере.
- Решите, как игроки будут взаимодействовать с этим функционалом (через команды в чате, интерфейс игры и т. д.).

3. Работа с API игры Rust:
- Используйте API игры Rust для создания кровати в заданных местах (городе и бандитском лагере).
- Проверьте документацию API для понимания доступных методов и возможностей.

4. Логика создания кровати:
- Реализуйте логику, которая позволит игрокам создавать кровать в городе и в бандитском лагере.
- Убедитесь, что создание кровати соответствует правилам и механике игры.

5. Тестирование и отладка:
- Протестируйте функционал создания кровати в городе и в бандитском лагере.
- Проведите отладку для исправления возможных ошибок и недочетов.

6. Развертывание плагина:
- Разверните ваш плагин на сервере Rust и позвольте игрокам использовать функционал создания кровати.

Это общий план действий для создания плагина, который создаст кровать в городе и в бандитском лагере для игры Rust. Учитывайте, что для взаимодействия с игрой Rust могут потребоваться дополнительные шаги и настройки. Если у вас возникнут дополнительные вопросы или потребуется дополнительная помощь, не стесняйтесь обращаться.
напиши плагин который создаст кровать в городе и в бандитском лагере для игры rust
 
напиши плагин который создаст кровать в городе и в бандитском лагере для игры rust
Для создания плагина, который создаст кровать в городе и в бандитском лагере для игры Rust, вам потребуется использовать Rust и, возможно, фреймворк Rocket для веб-разработки. Вам также понадобится доступ к API игры Rust для взаимодействия с миром игры. Ниже приведен пример кода на Rust, который может помочь вам начать с создания плагина для создания кровати в городе и в бандитском лагере:

Код:
use rocket::http::Status;
use rocket::response::status;
use rocket::State;
use std::sync::{Arc, Mutex};

// Структура для представления кровати
#[derive(Debug, Clone)]
struct Bed {
    location: String,
    owner: Option<String>,
}

// Состояние кроватей в городе
struct CityBeds {
    beds: Arc<Mutex<Vec<Bed>>>,
}

// Состояние кроватей в бандитском лагере
struct BanditCampBeds {
    beds: Arc<Mutex<Vec<Bed>>>,
}

#[get("/city/beds")]
fn get_city_beds(city_beds: State<CityBeds>) -> status::Custom<String> {
    let beds = city_beds.beds.lock().unwrap();
    status::Custom(Status::Ok, format!("City Beds: {:?}", beds))
}

#[get("/bandit-camp/beds")]
fn get_bandit_camp_beds(bandit_camp_beds: State<BanditCampBeds>) -> status::Custom<String> {
    let beds = bandit_camp_beds.beds.lock().unwrap();
    status::Custom(Status::Ok, format!("Bandit Camp Beds: {:?}", beds))
}

fn main() {
    let city_beds = Arc::new(Mutex::new(vec![
        Bed {
            location: "City".to_string(),
            owner: None,
        },
    ]));

    let bandit_camp_beds = Arc::new(Mutex::new(vec![
        Bed {
            location: "Bandit Camp".to_string(),
            owner: None,
        },
    ]));

    rocket::ignite()
        .mount("/api", routes![get_city_beds, get_bandit_camp_beds])
        .manage(CityBeds { beds: city_beds })
        .manage(BanditCampBeds { beds: bandit_camp_beds })
        .launch();
}

Этот код представляет простой пример использования Rocket для создания REST API, которое позволяет получить информацию о кроватях в городе и в бандитском лагере. Вам нужно будет доработать код, чтобы добавить функционал создания кроватей и их аренды в различных местах игры. Надеюсь, этот пример будет полезным для вашего проекта. Если у вас возникнут дополнительные вопросы или понадобится дополнительная помощь, не стесняйтесь задать их.
 
Для создания плагина, который создаст кровать в городе и в бандитском лагере для игры Rust, вам потребуется использовать Rust и, возможно, фреймворк Rocket для веб-разработки. Вам также понадобится доступ к API игры Rust для взаимодействия с миром игры. Ниже приведен пример кода на Rust, который может помочь вам начать с создания плагина для создания кровати в городе и в бандитском лагере:

Код:
use rocket::http::Status;
use rocket::response::status;
use rocket::State;
use std::sync::{Arc, Mutex};

// Структура для представления кровати
#[derive(Debug, Clone)]
struct Bed {
    location: String,
    owner: Option<String>,
}

// Состояние кроватей в городе
struct CityBeds {
    beds: Arc<Mutex<Vec<Bed>>>,
}

// Состояние кроватей в бандитском лагере
struct BanditCampBeds {
    beds: Arc<Mutex<Vec<Bed>>>,
}

#[get("/city/beds")]
fn get_city_beds(city_beds: State<CityBeds>) -> status::Custom<String> {
    let beds = city_beds.beds.lock().unwrap();
    status::Custom(Status::Ok, format!("City Beds: {:?}", beds))
}

#[get("/bandit-camp/beds")]
fn get_bandit_camp_beds(bandit_camp_beds: State<BanditCampBeds>) -> status::Custom<String> {
    let beds = bandit_camp_beds.beds.lock().unwrap();
    status::Custom(Status::Ok, format!("Bandit Camp Beds: {:?}", beds))
}

fn main() {
    let city_beds = Arc::new(Mutex::new(vec![
        Bed {
            location: "City".to_string(),
            owner: None,
        },
    ]));

    let bandit_camp_beds = Arc::new(Mutex::new(vec![
        Bed {
            location: "Bandit Camp".to_string(),
            owner: None,
        },
    ]));

    rocket::ignite()
        .mount("/api", routes![get_city_beds, get_bandit_camp_beds])
        .manage(CityBeds { beds: city_beds })
        .manage(BanditCampBeds { beds: bandit_camp_beds })
        .launch();
}

Этот код представляет простой пример использования Rocket для создания REST API, которое позволяет получить информацию о кроватях в городе и в бандитском лагере. Вам нужно будет доработать код, чтобы добавить функционал создания кроватей и их аренды в различных местах игры. Надеюсь, этот пример будет полезным для вашего проекта. Если у вас возникнут дополнительные вопросы или понадобится дополнительная помощь, не стесняйтесь задать
сделай так чтобы при нажатии на них на карте можно было встать в этом месте
 
сделай так чтобы при нажатии на них на карте можно было встать в этом месте
Для реализации функционала, который позволит игрокам с помощью плагина встать в определенном месте на карте при нажатии на кровать в городе или в бандитском лагере в игре Rust, вам понадобится настроить взаимодействие между вашим плагином и игровым миром. Вам также потребуется использовать API игры Rust для выполнения этой функции.

Ниже приведен общий план того, как можно реализовать данную функциональность:

1. Определение местоположения игрока:
- После нажатия на кровать в городе или в бандитском лагере, определите местоположение игрока на карте.

2. Перемещение игрока:
- С помощью API игры Rust, переместите игрока в выбранное место на карте, соответствующее местоположению кровати.

3. Обновление информации о местоположении игрока:
- Обновите информацию о местоположении игрока в игровом мире, чтобы он появился в правильном месте после нажатия на кровать.

4. Обработка событий клика на кровать:
- Настройте обработку событий клика на кровать в вашем плагине, чтобы запускать процесс перемещения игрока.

5. Тестирование и отладка:
- Проведите тестирование функционала, чтобы убедиться, что игрок может успешно встать в выбранном месте на карте после нажатия на кровать.
- Выполните отладку для исправления возможных ошибок и недочетов.

Это общий план действий для реализации функционала, который позволит игрокам встать в определенном месте на карте после нажатия на кровать в городе или в бандитском лагере в игре Rust. Необходимо учитывать специфику API игры Rust и возможные ограничения. Если у вас возникнут дополнительные вопросы или потребуется дополнительная помощь, не стесняйтесь обращаться.
 
Похоже, что ошибка "Error while compiling restart: ; expected | Line: 1, Pos: 11" указывает на то, что возможно в вашем коде есть проблема с синтаксисом или неправильным размещением символов. Давайте проанализируем код, чтобы найти и исправить ошибку.

Вот ваш обновленный код с русским языком:

Код:
use rocket::response::content;
use std::time::{SystemTime, UNIX_EPOCH};
use std::process::Command;

#[derive(Debug)]
struct PluginSettings {
    background_color: String,
    restart_time: u64,
    font_size: String,
    window_size: String,
}

impl PluginSettings {
    fn new(background_color: String, restart_time: u64, font_size: String, window_size: String) -> Self {
        PluginSettings { background_color, restart_time, font_size, window_size }
    }
}

#[get("/restart_warning/<position>?<background_color>&<restart_time>&<font_size>&<window_size>")]
fn restart_warning(position: Option<String>, background_color: Option<String>, restart_time: Option<u64>, font_size: Option<String>, window_size: Option<String>) -> content::Html<String> {
    let position = position.unwrap_or_else(|| "top".to_string());
    let background_color = background_color.unwrap_or_else(|| "yellow".to_string());
    let restart_time = restart_time.unwrap_or_else(|| 600);
    let font_size = font_size.unwrap_or_else(|| "16px".to_string());
    let window_size = window_size.unwrap_or_else(|| "200px".to_string());

    let style = match position.as_str() {
        "top" => "top: 10px; left: 50%; transform: translateX(-50%);",
        "bottom" => "bottom: 10px; left: 50%; transform: translateX(-50%);",
        "left" => "top: 50%; left: 10px; transform: translateY(-50%);",
        "right" => "top: 50%; right: 10px; transform: translateY(-50%);",
        _ => "top: 10px; left: 50%; transform: translateX(-50%);",
    };

    if restart_time == 0 {
        let output = Command::new("systemctl")
            .args(&["restart", "rust_server.service"])
            .output()
            .expect("failed to execute process");

        println!("Сервер перезапущен: {:?}", output);
    }

    let html = format!(
        r#"<div style='background-color: {}; text-align: center; padding: 10px; position: fixed; {}; font-size: {}; width: {};'>Сервер будет перезапущен через {} секунд!</div>"#,
        background_color, style, font_size, window_size, restart_time
    );

    content::Html(html)
}

fn main() {
    rocket::ignite().mount("/", routes![restart_warning]).launch();
}

Пожалуйста, скопируйте и вставьте этот код в ваш проект и попробуйте скомпилировать его снова. Если ошибка остается, пожалуйста, предоставьте дополнительную информацию о коде или сообщения об ошибках, чтобы я мог помочь вам еще более точно.
исправь ошибку Error while compiling slip: ; expected | Line: 1, Pos: 11
 
исправь ошибку Error while compiling slip: ; expected | Line: 1, Pos: 11
Ошибка "Error while compiling slip: ; expected | Line: 1, Pos: 11" указывает на то, что в вашем коде возможно пропущена точка с запятой или есть проблема с размещением символов. Давайте вместе посмотрим на ваш код и попробуем найти и исправить ошибку.

Чтобы помочь вам точнее, мне нужно увидеть ваш код. Пожалуйста, предоставьте фрагмент кода или весь код, который вызывает эту ошибку, и я постараюсь помочь вам исправить проблему.
 
Ошибка "Error while compiling slip: ; expected | Line: 1, Pos: 11" указывает на то, что в вашем коде возможно пропущена точка с запятой или есть проблема с размещением символов. Давайте вместе посмотрим на ваш код и попробуем найти и исправить ошибку.

Чтобы помочь вам точнее, мне нужно увидеть ваш код. Пожалуйста, предоставьте фрагмент кода или весь код, который вызывает эту ошибку, и я постараюсь помочь вам исправить проблему.
use rocket::response::content;
use std::time::{SystemTime, UNIX_EPOCH};
use std::process::Command;

#[derive(Debug)]
struct PluginSettings {
background_color: String,
restart_time: u64,
font_size: String,
window_size: String,
}

impl PluginSettings {
fn new(background_color: String, restart_time: u64, font_size: String, window_size: String) -> Self {
PluginSettings { background_color, restart_time, font_size, window_size }
}
}

#[get("/restart_warning/<position>?<background_color>&<restart_time>&<font_size>&<window_size>")]
fn restart_warning(position: Option<String>, background_color: Option<String>, restart_time: Option<u64>, font_size: Option<String>, window_size: Option<String>) -> content::Html<String> {
let position = position.unwrap_or_else(|| "top".to_string());
let background_color = background_color.unwrap_or_else(|| "yellow".to_string());
let restart_time = restart_time.unwrap_or_else(|| 600);
let font_size = font_size.unwrap_or_else(|| "16px".to_string());
let window_size = window_size.unwrap_or_else(|| "200px".to_string());

let style = match position.as_str() {
"top" => "top: 10px; left: 50%; transform: translateX(-50%);",
"bottom" => "bottom: 10px; left: 50%; transform: translateX(-50%);",
"left" => "top: 50%; left: 10px; transform: translateY(-50%);",
"right" => "top: 50%; right: 10px; transform: translateY(-50%);",
_ => "top: 10px; left: 50%; transform: translateX(-50%);",
};

if restart_time == 0 {
let output = Command::new("systemctl")
.args(&["restart", "rust_server.service"])
.output()
.expect("failed to execute process");

println!("Сервер перезапущен: {:?}", output);
}

let html = format!(
r#"<div style='background-color: {}; text-align: center; padding: 10px; position: fixed; {}; font-size: {}; width: {};'>Сервер будет перезапущен через {} секунд!</div>"#,
background_color, style, font_size, window_size, restart_time
);

content::Html(html)
}

fn main() {
rocket::ignite().mount("/", routes![restart_warning]).launch();
}
 
use rocket::response::content;
use std::time::{SystemTime, UNIX_EPOCH};
use std::process::Command;

#[derive(Debug)]
struct PluginSettings {
background_color: String,
restart_time: u64,
font_size: String,
window_size: String,
}

impl PluginSettings {
fn new(background_color: String, restart_time: u64, font_size: String, window_size: String) -> Self {
PluginSettings { background_color, restart_time, font_size, window_size }
}
}

#[get("/restart_warning/<position>?<background_color>&<restart_time>&<font_size>&<window_size>")]
fn restart_warning(position: Option<String>, background_color: Option<String>, restart_time: Option<u64>, font_size: Option<String>, window_size: Option<String>) -> content::Html<String> {
let position = position.unwrap_or_else(|| "top".to_string());
let background_color = background_color.unwrap_or_else(|| "yellow".to_string());
let restart_time = restart_time.unwrap_or_else(|| 600);
let font_size = font_size.unwrap_or_else(|| "16px".to_string());
let window_size = window_size.unwrap_or_else(|| "200px".to_string());

let style = match position.as_str() {
"top" => "top: 10px; left: 50%; transform: translateX(-50%);",
"bottom" => "bottom: 10px; left: 50%; transform: translateX(-50%);",
"left" => "top: 50%; left: 10px; transform: translateY(-50%);",
"right" => "top: 50%; right: 10px; transform: translateY(-50%);",
_ => "top: 10px; left: 50%; transform: translateX(-50%);",
};

if restart_time == 0 {
let output = Command::new("systemctl")
.args(&["restart", "rust_server.service"])
.output()
.expect("failed to execute process");

println!("Сервер перезапущен: {:?}", output);
}

let html = format!(
r#"<div style='background-color: {}; text-align: center; padding: 10px; position: fixed; {}; font-size: {}; width: {};'>Сервер будет перезапущен через {} секунд!</div>"#,
background_color, style, font_size, window_size, restart_time
);

content::Html(html)
}

fn main() {
rocket::ignite().mount("/", routes![restart_warning]).launch();
}
Проблема с ошибкой "Error while compiling slip: ; expected | Line: 1, Pos: 11" в вашем коде скорее всего связана с тем, что компилятор ожидает другой символ в этой позиции. Посмотрите внимательно на ваш код и на строку, где произошла ошибка.

Возможно, причина ошибки заключается в окружающем коде или в настройках вашей среды разработки. Попробуйте выполнить следующие действия для устранения ошибки:

1. Убедитесь, что вы используете правильные версии библиотек и компилятора Rust.
2. Перезапустите вашу среду разработки и попробуйте скомпилировать код снова.
3. Проверьте внимательно все строки кода перед позицией, где возникла ошибка, чтобы найти возможные ошибки.

Если проблема сохраняется, попробуйте скомпилировать код в командной строке, чтобы получить более подробные сообщения об ошибках. Возможно, это поможет вам найти и исправить причину ошибки.

Если у вас возникнут дополнительные проблемы или вопросы, не стесняйтесь обращаться за помощью. Готов помочь вам в решении проблемы!
 
Привет! Чем могу помочь?
using Facepunch;
using Facepunch.Math;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;

namespace Oxide.Plugins
{
[Info("CompoundTeleport", "k1lly0u", "2.0.17")]
[Description("Allow players to respawn at, or teleport to the Outpost and Bandit Camp")]
class CompoundTeleport : RustPlugin
{
#region Fields
[PluginReference] Plugin NoEscape;

private Hash<ulong, Cooldown> cooldowns = new Hash<ulong, Cooldown>();

private Hash<ulong, Action> pending = new Hash<ulong, Action>();

private SpawnManager Outpost { get; set; }

private SpawnManager Bandit { get; set; }

private const string TELEPORT_PERMISSION = "compoundteleport.tp";
private const string RESPAWN_PERMISSION = "compoundteleport.respawn";
private const string ADMIN_PERMISSION = "compoundteleport.admin";

private const int TARGET_LAYERS = ~(1 << 10 | 1 << 18 | 1 << 28 | 1 << 29);

private const string RESPAWN_BAG_CMD = "respawn_sleepingbag";
private const string REMOVE_BAG_CMD = "respawn_sleepingbag_remove";
private const string RESPAWN_CMD = "respawn";

private static NetworkableId OUTPOST_ID = new NetworkableId(111);
private static NetworkableId BANDIT_ID = new NetworkableId(112);
#endregion

#region Oxide Hooks
private void Loaded()
{
lang.RegisterMessages(Messages, this);

permission.RegisterPermission(TELEPORT_PERMISSION, this);
permission.RegisterPermission(RESPAWN_PERMISSION, this);
permission.RegisterPermission(ADMIN_PERMISSION, this);

foreach (ConfigData.CustomSpawnPoint customSpawnPoint in configData.Custom)
{
if (customSpawnPoint.Enabled && customSpawnPoint.CanTeleportTo)
{
string name = customSpawnPoint.Name.Replace(" ", "").ToLower();

cmd.AddChatCommand(name, this,
(b, s, a) => cmdTeleportCustom(b, s, new []{customSpawnPoint.Name}));

Puts($"Registered teleport command /{name}");
}
}

foreach (KeyValuePair<string, ConfigData.TeleportOptions.VIP> kvp in configData.Teleport.VIPTimes)
permission.RegisterPermission(kvp.Key, this);

cmd.AddChatCommand(configData.Teleport.OutpostCommand, this, cmdTeleportOutpost);
cmd.AddChatCommand(configData.Teleport.BanditCommand, this, cmdTeleportBandit);
cmd.AddChatCommand(configData.Teleport.CancelCommand, this, cmdTeleportCancel);
}

private void OnServerInitialized()
{
GenerateSpawnPoints();

int index = 0;
foreach (ConfigData.CustomSpawnPoint customSpawnPoint in configData.Custom)
{
if (customSpawnPoint.Enabled)
{
customSpawnPoint.Setup(index);
index++;
}
}
}

private void OnPlayerDeath(BasePlayer player, HitInfo hitInfo) => CancelPendingTeleports(player);

private void OnRespawnInformationGiven(BasePlayer player, List<RespawnInformation.SpawnOptions> list)
{
if (!player || player.IsNpc || !player.IsConnected)
return;

if (!configData.Respawn.AllowBandit && !configData.Respawn.AllowOutpost)
return;

if (configData.Respawn.DisableIfHostile && player.IsHostile())
return;

if (!permission.UserHasPermission(player.UserIDString, RESPAWN_PERMISSION) && !permission.UserHasPermission(player.UserIDString, ADMIN_PERMISSION))
return;

if (NoEscape)
{
if (configData.NoEscape.RaidBlockedRespawn)
{
bool success = NoEscape.Call<bool>("IsRaidBlocked", player);
if (success)
{
SendReply(player, msg("Error.RaidBlocked", player.userID));
return;
}
}

if (configData.NoEscape.CombatBlockedRespawn)
{
bool success = NoEscape.Call<bool>("IsCombatBlocked", player);
if (success)
{
SendReply(player, msg("Error.CombatBlocked", player.userID));
return;
}
}
}

cooldowns.TryGetValue(player.userID, out Cooldown cooldown);

if (Outpost != null && configData.Respawn.AllowOutpost)
{
RespawnInformation.SpawnOptions d = Pool.Get<RespawnInformation.SpawnOptions>();
d.id = OUTPOST_ID;
d.name = msg("Name.Outpost", player.userID);
d.worldPosition = Outpost.Position;
d.type = RespawnInformation.SpawnOptions.RespawnType.Bed;
d.unlockSeconds = (cooldown?.respawn ?? 0) != 0 ? Mathf.Clamp((cooldown.respawn - Epoch.Current), 0, int.MaxValue) : 0;
d.respawnState = RespawnInformation.SpawnOptions.RespawnState.OK;
list.Add(d);
}

if (Bandit != null && configData.Respawn.AllowBandit)
{
RespawnInformation.SpawnOptions d = Pool.Get<RespawnInformation.SpawnOptions>();
d.id = BANDIT_ID;
d.name = msg("Name.Bandit", player.userID);
d.worldPosition = Bandit.Position;
d.type = RespawnInformation.SpawnOptions.RespawnType.Bed;
d.unlockSeconds = (cooldown?.respawn ?? 0) != 0 ? Mathf.Clamp((cooldown.respawn - Epoch.Current), 0, int.MaxValue) : 0;
d.respawnState = RespawnInformation.SpawnOptions.RespawnState.OK;
list.Add(d);
}

foreach (ConfigData.CustomSpawnPoint customSpawnPoint in configData.Custom)
{
if (customSpawnPoint.Enabled && customSpawnPoint.CanRespawnAt)
{
RespawnInformation.SpawnOptions d = Pool.Get<RespawnInformation.SpawnOptions>();
d.id = customSpawnPoint.Id;
d.name = customSpawnPoint.Name;
d.worldPosition = customSpawnPoint.WorldPosition;
d.type = RespawnInformation.SpawnOptions.RespawnType.Bed;
d.unlockSeconds = (cooldown?.respawn ?? 0) != 0 ? Mathf.Clamp((cooldown.respawn - Epoch.Current), 0, int.MaxValue) : 0;
d.respawnState = RespawnInformation.SpawnOptions.RespawnState.OK;
list.Add(d);
}
}
}

private object OnServerCommand(ConsoleSystem.Arg arg)
{
BasePlayer player = arg.Player();
if (player == null || !player.IsConnected)
return null;

if (configData.Respawn.DisableIfHostile && player.IsHostile())
return null;

if (player.IsDead() || player.IsSpectating())
{
if (arg.cmd.Name == RESPAWN_CMD)
{
if (configData.Respawn.ForceTo == "None")
return null;

if (configData.Respawn.ForceTo == "Outpost" && Outpost != null)
{
RespawnPlayerAt(player, Outpost.Get());
return false;
}

if (configData.Respawn.ForceTo == "Bandit" && Bandit != null)
{
RespawnPlayerAt(player, Bandit.Get());
return false;
}
}

if (arg.cmd.Name == REMOVE_BAG_CMD)
{
NetworkableId num = arg.GetEntityID(0);
if (num == OUTPOST_ID || num == BANDIT_ID)
return false;

if (configData.Custom.Any(x => x.Enabled && x.Id == num))
return false;
}

if (arg.cmd.Name == RESPAWN_BAG_CMD)
{
NetworkableId num = arg.GetEntityID(0);
if (num == OUTPOST_ID && Outpost != null)
{
RespawnPlayerAt(player, Outpost.Get());
return false;
}

if (num == BANDIT_ID && Bandit != null)
{
RespawnPlayerAt(player, Bandit.Get());
return false;
}

foreach (ConfigData.CustomSpawnPoint customSpawnPoint in configData.Custom)
{
if (customSpawnPoint.Enabled && customSpawnPoint.CanRespawnAt && customSpawnPoint.Id == num)
{
RespawnPlayerAt(player, customSpawnPoint.Manager.Get());
return false;
}
}
}
}
return null;
}

private void Unload()
{
foreach (BasePlayer player in BasePlayer.activePlayerList)
CancelPendingTeleports(player);
}
#endregion

#region Functions
private void GenerateSpawnPoints()
{
if (ConVar.Server.level == "HapisIsland")
Outpost = new SpawnManager(new Vector3(-211f, 105f, -432f), 40f, "road", "carpark", "pavement");
else
{
foreach (MonumentInfo monument in UnityEngine.Object.FindObjectsOfType<MonumentInfo>())
{
if (monument.name.Contains("/compound.prefab"))
Outpost = new SpawnManager(monument.transform.position, 40f, "road", "carpark", "pavement");
else if (monument.name.Contains("/bandit_town.prefab"))
Bandit = new SpawnManager(monument.transform.position, 80f, "walkway");
}
}

if (Outpost == null && Bandit == null && configData.Custom.Count == 0)
{
PrintError("Unable to find a Outpost or Bandit Camp on this map. Unable to continue...");
return;
}

if (Outpost != null)
Puts($"Generated {Outpost.Count} spawn points at the Outpost");

if (Bandit != null)
Puts($"Generated {Bandit.Count} spawn points at the Bandit Camp");
}

private void RespawnPlayerAt(BasePlayer player, Vector3 position)
{
if (!cooldowns.TryGetValue(player.userID, out Cooldown cooldown))
cooldowns[player.userID] = cooldown = new Cooldown();

player.RespawnAt(position, Quaternion.identity);
cooldown.respawn = Epoch.Current + configData.Respawn.Cooldown;
}

private bool HasPendingTeleports(BasePlayer player) => pending.ContainsKey(player.userID);

private void CancelPendingTeleports(BasePlayer player)
{
if (player == null)
return;

if (HasPendingTeleports(player))
{
player.CancelInvoke(pending[player.userID]);
pending.Remove(player.userID);
}
}
#endregion

#region Helpers
private string FormatTime(double time)
{
TimeSpan dateDifference = TimeSpan.FromSeconds((float)time);
int days = dateDifference.Days;
int hours = dateDifference.Hours + (days * 24);

int mins = dateDifference.Minutes;
int secs = dateDifference.Seconds;

if (hours > 0)
return $"{hours:00}h:{mins:00}m:{secs:00}s";
if (mins > 0)
return $"{mins:00}m:{secs:00}s";
return $"{secs:00}s";
}

private int GetCooldownTime(string playerId)
{
int cooldown = configData.Teleport.Cooldown;

foreach(KeyValuePair<string, ConfigData.TeleportOptions.VIP> kvp in configData.Teleport.VIPTimes)
{
if (permission.UserHasPermission(playerId, kvp.Key))
cooldown = kvp.Value.Cooldown;
}

return cooldown;
}

private int GetWaitTime(string playerId)
{
int wait = configData.Teleport.Wait;

foreach (KeyValuePair<string, ConfigData.TeleportOptions.VIP> kvp in configData.Teleport.VIPTimes)
{
if (permission.UserHasPermission(playerId, kvp.Key))
wait = kvp.Value.Wait;
}

return wait;
}

private void TeleportToOutpost(BasePlayer player) => MovePosition(player, Outpost.Get());

private void TeleportToBandit(BasePlayer player) => MovePosition(player, Bandit.Get());

private void MovePosition(BasePlayer player, Vector3 destination)
{
try
{
if (player.isMounted)
player.GetMounted().DismountPlayer(player, true);

player.SetParent(null, true, true);

player.StartSleeping();
player.SetPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot, true);

player.EnablePlayerCollider();
player.SetServerFall(true);

player.RemoveFromTriggers();

player.MovePosition(destination);
player.ClientRPCPlayer(null, player, "ForcePositionTo", destination);

player.UpdateNetworkGroup();
player.SendNetworkUpdateImmediate();
player.ClearEntityQueue();
player.SendFullSnapshot();
}
finally
{
//player.UpdatePlayerCollider(true);
//player.UpdatePlayerRigidbody(true);
player.EnablePlayerCollider();
//player.AddPlayerRigidbody();
player.SetServerFall(false);

if (!cooldowns.TryGetValue(player.userID, out Cooldown cooldown))
cooldowns[player.userID] = cooldown = new Cooldown();

cooldown.command = Epoch.Current + GetCooldownTime(player.UserIDString);

pending.Remove(player.userID);
}
}
#endregion

#region Spawn Handler
private class SpawnManager
{
private List<Vector3> _spawnPoints;
private List<Vector3> _availablePoints;

public int Count { get { return _spawnPoints.Count; } }

public Vector3 Position { get; private set; }

public SpawnManager() { }

public SpawnManager(Vector3 position, float size, params string[] targetNames)
{
_spawnPoints = new List<Vector3>();

for (int i = 0; i < 150; i++)
{
Vector3 p = position + (Random.insideUnitSphere * size);
p.y = position.y + 100f;

if (Physics.SphereCast(new Ray(p, Vector3.down), 0.5f, out RaycastHit rayHit, 150, TARGET_LAYERS, QueryTriggerInteraction.Ignore))
{
if (TerrainMeta.WaterMap.GetDepth(rayHit.point) > 0f)
continue;

if (rayHit.collider is TerrainCollider)
_spawnPoints.Add(rayHit.point);
else
{
if (targetNames != null)
{
if (targetNames.Any(rayHit.collider.name.Contains))
_spawnPoints.Add(rayHit.point);
}
}
}
}

_availablePoints = new List<Vector3>(_spawnPoints);

Position = position;
}

public Vector3 Get()
{
Vector3 point = _availablePoints.GetRandom();
_availablePoints.Remove(point);

if (_availablePoints.Count == 0)
_availablePoints = new List<Vector3>(_spawnPoints);

return point;
}
}
#endregion

#region Commands
private void cmdTeleportOutpost(BasePlayer player, string command, string[] args)
{
if (!MeetsAllRequirements(player))
return;

InvokeTeleport(player, () => TeleportToOutpost(player));

SendReply(player, string.Format(msg("Notification.TPPending", player.userID), msg("Name.Outpost", player.userID), FormatTime(GetWaitTime(player.UserIDString))));
}

private void cmdTeleportBandit(BasePlayer player, string command, string[] args)
{
if (!MeetsAllRequirements(player))
return;

InvokeTeleport(player, () => TeleportToBandit(player));

SendReply(player, string.Format(msg("Notification.TPPending", player.userID), msg("Name.Bandit", player.userID), FormatTime(GetWaitTime(player.UserIDString))));
}

private void cmdTeleportCustom(BasePlayer player, string command, string[] args)
{
if (configData.Custom.All(x => !x.Enabled))
{
SendReply(player, msg("Notification.NoAreas", player.userID));
return;
}

if (args == null || args.Length == 0)
{
SendReply(player, msg("Notification.NoAreaSpecified", player.userID));
return;
}

string name = string.Join(" ", args);

ConfigData.CustomSpawnPoint customSpawnPoint = null;
foreach (ConfigData.CustomSpawnPoint spawnPoint in configData.Custom)
{
if (spawnPoint.Enabled && spawnPoint.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
{
customSpawnPoint = spawnPoint;
break;
}
}

if (customSpawnPoint == null)
{
SendReply(player, string.Format(msg("Notification.NoAreaWithName", player.userID), name));
return;
}

if (!MeetsAllRequirements(player))
return;

InvokeTeleport(player, () => MovePosition(player, customSpawnPoint.Manager.Get()));

SendReply(player, string.Format(msg("Notification.TPPending", player.userID), customSpawnPoint.Name, FormatTime(GetWaitTime(player.UserIDString))));
}

private void InvokeTeleport(BasePlayer player, Action action)
{
player.Invoke(action, GetWaitTime(player.UserIDString));

pending[player.userID] = action;
}

private bool MeetsAllRequirements(BasePlayer player)
{
if (permission.UserHasPermission(player.UserIDString, ADMIN_PERMISSION))
return true;

if (!permission.UserHasPermission(player.UserIDString, TELEPORT_PERMISSION))
{
SendReply(player, msg("Error.NoPermission", player.userID));
return false;
}

if (HasPendingTeleports(player))
{
SendReply(player, msg("Error.TPPending", player.userID));
return false;
}

if (configData.Teleport.Hostile && player.IsHostile())
{
SendReply(player, msg("Error.Hostile", player.userID));
return false;
}

if (configData.Teleport.BuildingBlocked && player.IsBuildingBlocked())
{
SendReply(player, msg("Error.BuildingBlocked", player.userID));
return false;
}

if (cooldowns.TryGetValue(player.userID, out Cooldown cooldown))
{
int cooldownTime = cooldown.command - Epoch.Current;
if (cooldownTime > 0)
{
SendReply(player, string.Format(msg("Error.Cooldown", player.userID), FormatTime(cooldownTime)));
return false;
}
}

if (IsEscapeBlocked(player))
return false;

return true;
}

private void cmdTeleportCancel(BasePlayer player, string command, string[] args)
{
if (!HasPendingTeleports(player))
{
SendReply(player, msg("Notification.NonePending", player.userID));
return;
}

CancelPendingTeleports(player);
SendReply(player, msg("Notification.Cancelled", player.userID));
}
#endregion

#region Plugin Integration
private bool IsEscapeBlocked(BasePlayer player)
{
if (NoEscape)
{
if (configData.NoEscape.RaidBlocked)
{
bool success = NoEscape.Call<bool>("IsRaidBlocked", player);
if (success)
{
SendReply(player, msg("Error.RaidBlocked", player.userID));
return true;
}
}

if (configData.NoEscape.CombatBlocked)
{
bool success = NoEscape.Call<bool>("IsCombatBlocked", player);
if (success)
{
SendReply(player, msg("Error.CombatBlocked", player.userID));
return true;
}
}
}
return false;
}
#endregion

#region Config
private ConfigData configData;

private class ConfigData
{
[JsonProperty(PropertyName = "NoEscape Options")]
public NoEscapeOptions NoEscape { get; set; }

[JsonProperty(PropertyName = "Teleport Options")]
public TeleportOptions Teleport { get; set; }

[JsonProperty(PropertyName = "Respawn Options")]
public RespawnOptions Respawn { get; set; }

[JsonProperty(PropertyName = "Custom Spawn Points")]
public List<CustomSpawnPoint> Custom { get; set; }

public class TeleportOptions
{
[JsonProperty(PropertyName = "Amount of time to wait before teleporting (seconds)")]
public int Wait { get; set; }

[JsonProperty(PropertyName = "Cooldown time (seconds)")]
public int Cooldown { get; set; }

[JsonProperty(PropertyName = "Block teleport if player is hostile")]
public bool Hostile { get; set; }

[JsonProperty(PropertyName = "Block teleport if player is building blocked")]
public bool BuildingBlocked { get; set; }

[JsonProperty(PropertyName = "Teleport command name (Outpost)")]
public string OutpostCommand { get; set; }

[JsonProperty(PropertyName = "Teleport command name (Bandit Camp)")]
public string BanditCommand { get; set; }

[JsonProperty(PropertyName = "Teleport cancel command name")]
public string CancelCommand { get; set; }

[JsonProperty(PropertyName = "VIP Times")]
public Dictionary<string, VIP> VIPTimes { get; set; }

public class VIP
{
[JsonProperty(PropertyName = "Amount of time to wait before teleporting (seconds)")]
public int Wait { get; set; }

[JsonProperty(PropertyName = "Cooldown time (seconds)")]
public int Cooldown { get; set; }
}
}

public class CustomSpawnPoint
{
[JsonProperty(PropertyName = "The name of this area")]
public string Name { get; set; }

[JsonProperty(PropertyName = "Is this area enabled?")]
public bool Enabled { get; set; }

[JsonProperty(PropertyName = "Allow teleporting to this area")]
public bool CanTeleportTo { get; set; }

[JsonProperty(PropertyName = "Allow respawning at this area")]
public bool CanRespawnAt { get; set; }

[JsonProperty(PropertyName = "World position")]
public Vector3 WorldPosition { get; set; }

[JsonProperty(PropertyName = "Radius of points generated")]
public float Radius { get; set; }

[JsonProperty(PropertyName = "Names of potential raycast target valid for points")]
public string[] RaycastTargets { get; set; }

[JsonIgnore]
public SpawnManager Manager { get; set; }

[JsonIgnore]
public NetworkableId Id { get; set; }

public void Setup(int index)
{
Id = new NetworkableId((ulong)(113 + index));
Manager = new SpawnManager(WorldPosition, Radius, RaycastTargets);

if (Manager.Count == 0)
{
Interface.Oxide.LogInfo("[{0}] {1}", "CompoundTeleport", $"Failed to generate spawn points at {Name}");
Enabled = false;
}
else Interface.Oxide.LogInfo("[{0}] {1}", "CompoundTeleport", $"Generated {Manager.Count} spawn points at {Name}");
}

}

public class RespawnOptions
{
[JsonProperty(PropertyName = "Allow respawning at Outpost")]
public bool AllowOutpost { get; set; }

[JsonProperty(PropertyName = "Allow respawning at Bandit Camp")]
public bool AllowBandit { get; set; }

[JsonProperty(PropertyName = "Disable respawn options if player is hostile")]
public bool DisableIfHostile { get; set; }

[JsonProperty(PropertyName = "Cooldown time (seconds)")]
public int Cooldown { get; set; }

[JsonProperty(PropertyName = "Force respawns to (None, Outpost, Bandit)")]
public string ForceTo { get; set; }
}

public class NoEscapeOptions
{
[JsonProperty(PropertyName = "Block teleport when raid blocked")]
public bool RaidBlocked { get; set; }

[JsonProperty(PropertyName = "Block teleport when combat blocked")]
public bool CombatBlocked { get; set; }

[JsonProperty(PropertyName = "Disable respawn options when raid blocked")]
public bool RaidBlockedRespawn { get; set; }

[JsonProperty(PropertyName = "Disable respawn options when combat blocked")]
public bool CombatBlockedRespawn { get; set; }
}

public VersionNumber Version { get; set; }
}

protected override void LoadConfig()
{
base.LoadConfig();
configData = Config.ReadObject<ConfigData>();

if (configData.Version < Version)
UpdateConfigValues();

Config.WriteObject(configData, true);
}

protected override void LoadDefaultConfig() => configData = GetBaseConfig();

private ConfigData GetBaseConfig()
{
return new ConfigData
{
NoEscape = new ConfigData.NoEscapeOptions
{
CombatBlocked = true,
RaidBlocked = true,
CombatBlockedRespawn = true,
RaidBlockedRespawn = true,
},
Teleport = new ConfigData.TeleportOptions
{
BuildingBlocked = true,
BanditCommand = "bandit",
CancelCommand = "canceltp",
Cooldown = 300,
Hostile = true,
OutpostCommand = "outpost",
Wait = 10,
VIPTimes = new Dictionary<string, ConfigData.TeleportOptions.VIP>
{
["compoundteleport.vip1"] = new ConfigData.TeleportOptions.VIP { Cooldown = 150, Wait = 5 },
["compoundteleport.vip2"] = new ConfigData.TeleportOptions.VIP { Cooldown = 30, Wait = 3 },
}
},
Respawn = new ConfigData.RespawnOptions
{
Cooldown = 300,
ForceTo = "None",
AllowBandit = true,
AllowOutpost = true
},
Custom = new List<ConfigData.CustomSpawnPoint>
{
new ConfigData.CustomSpawnPoint
{
Name = "Example1",
Enabled = false,
CanTeleportTo = true,
CanRespawnAt = true,
WorldPosition = new Vector3(0, 0, 0),
Radius = 50,
RaycastTargets = new string[]{"road", "carpark", "pavement", "walkway"}
},
new ConfigData.CustomSpawnPoint
{
Name = "Example2",
Enabled = false,
CanTeleportTo = true,
CanRespawnAt = true,
WorldPosition = new Vector3(0, 0, 0),
Radius = 50,
RaycastTargets = new string[]{"road", "carpark", "pavement", "walkway"}
}
},
Version = Version
};
}

protected override void SaveConfig() => Config.WriteObject(configData, true);

private void UpdateConfigValues()
{
PrintWarning("Config update detected! Updating config values...");

ConfigData baseConfig = GetBaseConfig();

if (configData.Version < new VersionNumber(2, 0, 0))
configData = baseConfig;

if (configData.Version < new VersionNumber(2, 0, 6))
{
configData.NoEscape = baseConfig.NoEscape;
}

if (configData.Version < new VersionNumber(2, 0, 7))
configData.Teleport.VIPTimes = baseConfig.Teleport.VIPTimes;

if (configData.Version < new VersionNumber(2, 0, 16))
configData.Custom = baseConfig.Custom;

configData.Version = Version;
PrintWarning("Config update completed!");
}
#endregion

#region Data
private class Cooldown
{
public int respawn;
public int command;
}
#endregion

#region Localization
private string msg(string key, ulong playerId = 0UL) => lang.GetMessage(key, this, playerId != 0UL ? playerId.ToString() : null);

private Dictionary<string, string> Messages = new Dictionary<string, string>
{
["Name.Outpost"] = "Outpost",
["Name.Bandit"] = "Bandit Camp",
["Error.NoPermission"] = "You do not have permission to use this command",
["Error.TPPending"] = "You already have a teleport pending",
["Error.Hostile"] = "You can not teleport whilst you are marked hostile",
["Error.Cooldown"] = "You must wait another <color=#ce422b>{0}</color> before teleporting again",
["Error.RaidBlocked"] = "You can not teleport while <color=#ce422b>raid blocked</color>!",
["Error.CombatBlocked"] = "You can not teleport while <color=#ce422b>combat blocked</color>!",
["Error.BuildingBlocked"] = "You can not teleport while <color=#ce422b>building blocked</color>!",
["Notification.TPPending"] = "Teleporting to <color=#ce422b>{0}</color> in <color=#ce422b>{1}</color>",
["Notification.NonePending"] = "You do not have any teleports pending",
["Notification.Cancelled"] = "Cancelled pending teleports",
["Notification.NoAreas"] = "No custom spawn areas have been setup",
["Notification.NoAreaWithName"] = "No spawn area found with the name : {0}",
["Notification.NoAreaSpecified"] = "No area specified"
};
#endregion
}
}
 
удали телепортацию из плагина оставь только спавн
using Facepunch;
using Facepunch.Math;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;

namespace Oxide.Plugins
{
[Info("CompoundTeleport", "k1lly0u", "2.0.17")]
[Description("Allow players to respawn at, or teleport to the Outpost and Bandit Camp")]
class CompoundTeleport : RustPlugin
{
#region Fields
[PluginReference] Plugin NoEscape;

private Hash<ulong, Cooldown> cooldowns = new Hash<ulong, Cooldown>();

private Hash<ulong, Action> pending = new Hash<ulong, Action>();

private SpawnManager Outpost { get; set; }

private SpawnManager Bandit { get; set; }

private const string TELEPORT_PERMISSION = "compoundteleport.tp";
private const string RESPAWN_PERMISSION = "compoundteleport.respawn";
private const string ADMIN_PERMISSION = "compoundteleport.admin";

private const int TARGET_LAYERS = ~(1 << 10 | 1 << 18 | 1 << 28 | 1 << 29);

private const string RESPAWN_BAG_CMD = "respawn_sleepingbag";
private const string REMOVE_BAG_CMD = "respawn_sleepingbag_remove";
private const string RESPAWN_CMD = "respawn";

private static NetworkableId OUTPOST_ID = new NetworkableId(111);
private static NetworkableId BANDIT_ID = new NetworkableId(112);
#endregion

#region Oxide Hooks
private void Loaded()
{
lang.RegisterMessages(Messages, this);

permission.RegisterPermission(TELEPORT_PERMISSION, this);
permission.RegisterPermission(RESPAWN_PERMISSION, this);
permission.RegisterPermission(ADMIN_PERMISSION, this);

foreach (ConfigData.CustomSpawnPoint customSpawnPoint in configData.Custom)
{
if (customSpawnPoint.Enabled && customSpawnPoint.CanTeleportTo)
{
string name = customSpawnPoint.Name.Replace(" ", "").ToLower();

cmd.AddChatCommand(name, this,
(b, s, a) => cmdTeleportCustom(b, s, new []{customSpawnPoint.Name}));

Puts($"Registered teleport command /{name}");
}
}

foreach (KeyValuePair<string, ConfigData.TeleportOptions.VIP> kvp in configData.Teleport.VIPTimes)
permission.RegisterPermission(kvp.Key, this);

cmd.AddChatCommand(configData.Teleport.OutpostCommand, this, cmdTeleportOutpost);
cmd.AddChatCommand(configData.Teleport.BanditCommand, this, cmdTeleportBandit);
cmd.AddChatCommand(configData.Teleport.CancelCommand, this, cmdTeleportCancel);
}

private void OnServerInitialized()
{
GenerateSpawnPoints();

int index = 0;
foreach (ConfigData.CustomSpawnPoint customSpawnPoint in configData.Custom)
{
if (customSpawnPoint.Enabled)
{
customSpawnPoint.Setup(index);
index++;
}
}
}

private void OnPlayerDeath(BasePlayer player, HitInfo hitInfo) => CancelPendingTeleports(player);

private void OnRespawnInformationGiven(BasePlayer player, List<RespawnInformation.SpawnOptions> list)
{
if (!player || player.IsNpc || !player.IsConnected)
return;

if (!configData.Respawn.AllowBandit && !configData.Respawn.AllowOutpost)
return;

if (configData.Respawn.DisableIfHostile && player.IsHostile())
return;

if (!permission.UserHasPermission(player.UserIDString, RESPAWN_PERMISSION) && !permission.UserHasPermission(player.UserIDString, ADMIN_PERMISSION))
return;

if (NoEscape)
{
if (configData.NoEscape.RaidBlockedRespawn)
{
bool success = NoEscape.Call<bool>("IsRaidBlocked", player);
if (success)
{
SendReply(player, msg("Error.RaidBlocked", player.userID));
return;
}
}

if (configData.NoEscape.CombatBlockedRespawn)
{
bool success = NoEscape.Call<bool>("IsCombatBlocked", player);
if (success)
{
SendReply(player, msg("Error.CombatBlocked", player.userID));
return;
}
}
}

cooldowns.TryGetValue(player.userID, out Cooldown cooldown);

if (Outpost != null && configData.Respawn.AllowOutpost)
{
RespawnInformation.SpawnOptions d = Pool.Get<RespawnInformation.SpawnOptions>();
d.id = OUTPOST_ID;
d.name = msg("Name.Outpost", player.userID);
d.worldPosition = Outpost.Position;
d.type = RespawnInformation.SpawnOptions.RespawnType.Bed;
d.unlockSeconds = (cooldown?.respawn ?? 0) != 0 ? Mathf.Clamp((cooldown.respawn - Epoch.Current), 0, int.MaxValue) : 0;
d.respawnState = RespawnInformation.SpawnOptions.RespawnState.OK;
list.Add(d);
}

if (Bandit != null && configData.Respawn.AllowBandit)
{
RespawnInformation.SpawnOptions d = Pool.Get<RespawnInformation.SpawnOptions>();
d.id = BANDIT_ID;
d.name = msg("Name.Bandit", player.userID);
d.worldPosition = Bandit.Position;
d.type = RespawnInformation.SpawnOptions.RespawnType.Bed;
d.unlockSeconds = (cooldown?.respawn ?? 0) != 0 ? Mathf.Clamp((cooldown.respawn - Epoch.Current), 0, int.MaxValue) : 0;
d.respawnState = RespawnInformation.SpawnOptions.RespawnState.OK;
list.Add(d);
}

foreach (ConfigData.CustomSpawnPoint customSpawnPoint in configData.Custom)
{
if (customSpawnPoint.Enabled && customSpawnPoint.CanRespawnAt)
{
RespawnInformation.SpawnOptions d = Pool.Get<RespawnInformation.SpawnOptions>();
d.id = customSpawnPoint.Id;
d.name = customSpawnPoint.Name;
d.worldPosition = customSpawnPoint.WorldPosition;
d.type = RespawnInformation.SpawnOptions.RespawnType.Bed;
d.unlockSeconds = (cooldown?.respawn ?? 0) != 0 ? Mathf.Clamp((cooldown.respawn - Epoch.Current), 0, int.MaxValue) : 0;
d.respawnState = RespawnInformation.SpawnOptions.RespawnState.OK;
list.Add(d);
}
}
}

private object OnServerCommand(ConsoleSystem.Arg arg)
{
BasePlayer player = arg.Player();
if (player == null || !player.IsConnected)
return null;

if (configData.Respawn.DisableIfHostile && player.IsHostile())
return null;

if (player.IsDead() || player.IsSpectating())
{
if (arg.cmd.Name == RESPAWN_CMD)
{
if (configData.Respawn.ForceTo == "None")
return null;

if (configData.Respawn.ForceTo == "Outpost" && Outpost != null)
{
RespawnPlayerAt(player, Outpost.Get());
return false;
}

if (configData.Respawn.ForceTo == "Bandit" && Bandit != null)
{
RespawnPlayerAt(player, Bandit.Get());
return false;
}
}

if (arg.cmd.Name == REMOVE_BAG_CMD)
{
NetworkableId num = arg.GetEntityID(0);
if (num == OUTPOST_ID || num == BANDIT_ID)
return false;

if (configData.Custom.Any(x => x.Enabled && x.Id == num))
return false;
}

if (arg.cmd.Name == RESPAWN_BAG_CMD)
{
NetworkableId num = arg.GetEntityID(0);
if (num == OUTPOST_ID && Outpost != null)
{
RespawnPlayerAt(player, Outpost.Get());
return false;
}

if (num == BANDIT_ID && Bandit != null)
{
RespawnPlayerAt(player, Bandit.Get());
return false;
}

foreach (ConfigData.CustomSpawnPoint customSpawnPoint in configData.Custom)
{
if (customSpawnPoint.Enabled && customSpawnPoint.CanRespawnAt && customSpawnPoint.Id == num)
{
RespawnPlayerAt(player, customSpawnPoint.Manager.Get());
return false;
}
}
}
}
return null;
}

private void Unload()
{
foreach (BasePlayer player in BasePlayer.activePlayerList)
CancelPendingTeleports(player);
}
#endregion

#region Functions
private void GenerateSpawnPoints()
{
if (ConVar.Server.level == "HapisIsland")
Outpost = new SpawnManager(new Vector3(-211f, 105f, -432f), 40f, "road", "carpark", "pavement");
else
{
foreach (MonumentInfo monument in UnityEngine.Object.FindObjectsOfType<MonumentInfo>())
{
if (monument.name.Contains("/compound.prefab"))
Outpost = new SpawnManager(monument.transform.position, 40f, "road", "carpark", "pavement");
else if (monument.name.Contains("/bandit_town.prefab"))
Bandit = new SpawnManager(monument.transform.position, 80f, "walkway");
}
}

if (Outpost == null && Bandit == null && configData.Custom.Count == 0)
{
PrintError("Unable to find a Outpost or Bandit Camp on this map. Unable to continue...");
return;
}

if (Outpost != null)
Puts($"Generated {Outpost.Count} spawn points at the Outpost");

if (Bandit != null)
Puts($"Generated {Bandit.Count} spawn points at the Bandit Camp");
}

private void RespawnPlayerAt(BasePlayer player, Vector3 position)
{
if (!cooldowns.TryGetValue(player.userID, out Cooldown cooldown))
cooldowns[player.userID] = cooldown = new Cooldown();

player.RespawnAt(position, Quaternion.identity);
cooldown.respawn = Epoch.Current + configData.Respawn.Cooldown;
}

private bool HasPendingTeleports(BasePlayer player) => pending.ContainsKey(player.userID);

private void CancelPendingTeleports(BasePlayer player)
{
if (player == null)
return;

if (HasPendingTeleports(player))
{
player.CancelInvoke(pending[player.userID]);
pending.Remove(player.userID);
}
}
#endregion

#region Helpers
private string FormatTime(double time)
{
TimeSpan dateDifference = TimeSpan.FromSeconds((float)time);
int days = dateDifference.Days;
int hours = dateDifference.Hours + (days * 24);

int mins = dateDifference.Minutes;
int secs = dateDifference.Seconds;

if (hours > 0)
return $"{hours:00}h:{mins:00}m:{secs:00}s";
if (mins > 0)
return $"{mins:00}m:{secs:00}s";
return $"{secs:00}s";
}

private int GetCooldownTime(string playerId)
{
int cooldown = configData.Teleport.Cooldown;

foreach(KeyValuePair<string, ConfigData.TeleportOptions.VIP> kvp in configData.Teleport.VIPTimes)
{
if (permission.UserHasPermission(playerId, kvp.Key))
cooldown = kvp.Value.Cooldown;
}

return cooldown;
}

private int GetWaitTime(string playerId)
{
int wait = configData.Teleport.Wait;

foreach (KeyValuePair<string, ConfigData.TeleportOptions.VIP> kvp in configData.Teleport.VIPTimes)
{
if (permission.UserHasPermission(playerId, kvp.Key))
wait = kvp.Value.Wait;
}

return wait;
}

private void TeleportToOutpost(BasePlayer player) => MovePosition(player, Outpost.Get());

private void TeleportToBandit(BasePlayer player) => MovePosition(player, Bandit.Get());

private void MovePosition(BasePlayer player, Vector3 destination)
{
try
{
if (player.isMounted)
player.GetMounted().DismountPlayer(player, true);

player.SetParent(null, true, true);

player.StartSleeping();
player.SetPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot, true);

player.EnablePlayerCollider();
player.SetServerFall(true);

player.RemoveFromTriggers();

player.MovePosition(destination);
player.ClientRPCPlayer(null, player, "ForcePositionTo", destination);

player.UpdateNetworkGroup();
player.SendNetworkUpdateImmediate();
player.ClearEntityQueue();
player.SendFullSnapshot();
}
finally
{
//player.UpdatePlayerCollider(true);
//player.UpdatePlayerRigidbody(true);
player.EnablePlayerCollider();
//player.AddPlayerRigidbody();
player.SetServerFall(false);

if (!cooldowns.TryGetValue(player.userID, out Cooldown cooldown))
cooldowns[player.userID] = cooldown = new Cooldown();

cooldown.command = Epoch.Current + GetCooldownTime(player.UserIDString);

pending.Remove(player.userID);
}
}
#endregion

#region Spawn Handler
private class SpawnManager
{
private List<Vector3> _spawnPoints;
private List<Vector3> _availablePoints;

public int Count { get { return _spawnPoints.Count; } }

public Vector3 Position { get; private set; }

public SpawnManager() { }

public SpawnManager(Vector3 position, float size, params string[] targetNames)
{
_spawnPoints = new List<Vector3>();

for (int i = 0; i < 150; i++)
{
Vector3 p = position + (Random.insideUnitSphere * size);
p.y = position.y + 100f;

if (Physics.SphereCast(new Ray(p, Vector3.down), 0.5f, out RaycastHit rayHit, 150, TARGET_LAYERS, QueryTriggerInteraction.Ignore))
{
if (TerrainMeta.WaterMap.GetDepth(rayHit.point) > 0f)
continue;

if (rayHit.collider is TerrainCollider)
_spawnPoints.Add(rayHit.point);
else
{
if (targetNames != null)
{
if (targetNames.Any(rayHit.collider.name.Contains))
_spawnPoints.Add(rayHit.point);
}
}
}
}

_availablePoints = new List<Vector3>(_spawnPoints);

Position = position;
}

public Vector3 Get()
{
Vector3 point = _availablePoints.GetRandom();
_availablePoints.Remove(point);

if (_availablePoints.Count == 0)
_availablePoints = new List<Vector3>(_spawnPoints);

return point;
}
}
#endregion

#region Commands
private void cmdTeleportOutpost(BasePlayer player, string command, string[] args)
{
if (!MeetsAllRequirements(player))
return;

InvokeTeleport(player, () => TeleportToOutpost(player));

SendReply(player, string.Format(msg("Notification.TPPending", player.userID), msg("Name.Outpost", player.userID), FormatTime(GetWaitTime(player.UserIDString))));
}

private void cmdTeleportBandit(BasePlayer player, string command, string[] args)
{
if (!MeetsAllRequirements(player))
return;

InvokeTeleport(player, () => TeleportToBandit(player));

SendReply(player, string.Format(msg("Notification.TPPending", player.userID), msg("Name.Bandit", player.userID), FormatTime(GetWaitTime(player.UserIDString))));
}

private void cmdTeleportCustom(BasePlayer player, string command, string[] args)
{
if (configData.Custom.All(x => !x.Enabled))
{
SendReply(player, msg("Notification.NoAreas", player.userID));
return;
}

if (args == null || args.Length == 0)
{
SendReply(player, msg("Notification.NoAreaSpecified", player.userID));
return;
}

string name = string.Join(" ", args);

ConfigData.CustomSpawnPoint customSpawnPoint = null;
foreach (ConfigData.CustomSpawnPoint spawnPoint in configData.Custom)
{
if (spawnPoint.Enabled && spawnPoint.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
{
customSpawnPoint = spawnPoint;
break;
}
}

if (customSpawnPoint == null)
{
SendReply(player, string.Format(msg("Notification.NoAreaWithName", player.userID), name));
return;
}

if (!MeetsAllRequirements(player))
return;

InvokeTeleport(player, () => MovePosition(player, customSpawnPoint.Manager.Get()));

SendReply(player, string.Format(msg("Notification.TPPending", player.userID), customSpawnPoint.Name, FormatTime(GetWaitTime(player.UserIDString))));
}

private void InvokeTeleport(BasePlayer player, Action action)
{
player.Invoke(action, GetWaitTime(player.UserIDString));

pending[player.userID] = action;
}

private bool MeetsAllRequirements(BasePlayer player)
{
if (permission.UserHasPermission(player.UserIDString, ADMIN_PERMISSION))
return true;

if (!permission.UserHasPermission(player.UserIDString, TELEPORT_PERMISSION))
{
SendReply(player, msg("Error.NoPermission", player.userID));
return false;
}

if (HasPendingTeleports(player))
{
SendReply(player, msg("Error.TPPending", player.userID));
return false;
}

if (configData.Teleport.Hostile && player.IsHostile())
{
SendReply(player, msg("Error.Hostile", player.userID));
return false;
}

if (configData.Teleport.BuildingBlocked && player.IsBuildingBlocked())
{
SendReply(player, msg("Error.BuildingBlocked", player.userID));
return false;
}

if (cooldowns.TryGetValue(player.userID, out Cooldown cooldown))
{
int cooldownTime = cooldown.command - Epoch.Current;
if (cooldownTime > 0)
{
SendReply(player, string.Format(msg("Error.Cooldown", player.userID), FormatTime(cooldownTime)));
return false;
}
}

if (IsEscapeBlocked(player))
return false;

return true;
}

private void cmdTeleportCancel(BasePlayer player, string command, string[] args)
{
if (!HasPendingTeleports(player))
{
SendReply(player, msg("Notification.NonePending", player.userID));
return;
}

CancelPendingTeleports(player);
SendReply(player, msg("Notification.Cancelled", player.userID));
}
#endregion

#region Plugin Integration
private bool IsEscapeBlocked(BasePlayer player)
{
if (NoEscape)
{
if (configData.NoEscape.RaidBlocked)
{
bool success = NoEscape.Call<bool>("IsRaidBlocked", player);
if (success)
{
SendReply(player, msg("Error.RaidBlocked", player.userID));
return true;
}
}

if (configData.NoEscape.CombatBlocked)
{
bool success = NoEscape.Call<bool>("IsCombatBlocked", player);
if (success)
{
SendReply(player, msg("Error.CombatBlocked", player.userID));
return true;
}
}
}
return false;
}
#endregion

#region Config
private ConfigData configData;

private class ConfigData
{
[JsonProperty(PropertyName = "NoEscape Options")]
public NoEscapeOptions NoEscape { get; set; }

[JsonProperty(PropertyName = "Teleport Options")]
public TeleportOptions Teleport { get; set; }

[JsonProperty(PropertyName = "Respawn Options")]
public RespawnOptions Respawn { get; set; }

[JsonProperty(PropertyName = "Custom Spawn Points")]
public List<CustomSpawnPoint> Custom { get; set; }

public class TeleportOptions
{
[JsonProperty(PropertyName = "Amount of time to wait before teleporting (seconds)")]
public int Wait { get; set; }

[JsonProperty(PropertyName = "Cooldown time (seconds)")]
public int Cooldown { get; set; }

[JsonProperty(PropertyName = "Block teleport if player is hostile")]
public bool Hostile { get; set; }

[JsonProperty(PropertyName = "Block teleport if player is building blocked")]
public bool BuildingBlocked { get; set; }

[JsonProperty(PropertyName = "Teleport command name (Outpost)")]
public string OutpostCommand { get; set; }

[JsonProperty(PropertyName = "Teleport command name (Bandit Camp)")]
public string BanditCommand { get; set; }

[JsonProperty(PropertyName = "Teleport cancel command name")]
public string CancelCommand { get; set; }

[JsonProperty(PropertyName = "VIP Times")]
public Dictionary<string, VIP> VIPTimes { get; set; }

public class VIP
{
[JsonProperty(PropertyName = "Amount of time to wait before teleporting (seconds)")]
public int Wait { get; set; }

[JsonProperty(PropertyName = "Cooldown time (seconds)")]
public int Cooldown { get; set; }
}
}

public class CustomSpawnPoint
{
[JsonProperty(PropertyName = "The name of this area")]
public string Name { get; set; }

[JsonProperty(PropertyName = "Is this area enabled?")]
public bool Enabled { get; set; }

[JsonProperty(PropertyName = "Allow teleporting to this area")]
public bool CanTeleportTo { get; set; }

[JsonProperty(PropertyName = "Allow respawning at this area")]
public bool CanRespawnAt { get; set; }

[JsonProperty(PropertyName = "World position")]
public Vector3 WorldPosition { get; set; }

[JsonProperty(PropertyName = "Radius of points generated")]
public float Radius { get; set; }

[JsonProperty(PropertyName = "Names of potential raycast target valid for points")]
public string[] RaycastTargets { get; set; }

[JsonIgnore]
public SpawnManager Manager { get; set; }

[JsonIgnore]
public NetworkableId Id { get; set; }

public void Setup(int index)
{
Id = new NetworkableId((ulong)(113 + index));
Manager = new SpawnManager(WorldPosition, Radius, RaycastTargets);

if (Manager.Count == 0)
{
Interface.Oxide.LogInfo("[{0}] {1}", "CompoundTeleport", $"Failed to generate spawn points at {Name}");
Enabled = false;
}
else Interface.Oxide.LogInfo("[{0}] {1}", "CompoundTeleport", $"Generated {Manager.Count} spawn points at {Name}");
}

}

public class RespawnOptions
{
[JsonProperty(PropertyName = "Allow respawning at Outpost")]
public bool AllowOutpost { get; set; }

[JsonProperty(PropertyName = "Allow respawning at Bandit Camp")]
public bool AllowBandit { get; set; }

[JsonProperty(PropertyName = "Disable respawn options if player is hostile")]
public bool DisableIfHostile { get; set; }

[JsonProperty(PropertyName = "Cooldown time (seconds)")]
public int Cooldown { get; set; }

[JsonProperty(PropertyName = "Force respawns to (None, Outpost, Bandit)")]
public string ForceTo { get; set; }
}

public class NoEscapeOptions
{
[JsonProperty(PropertyName = "Block teleport when raid blocked")]
public bool RaidBlocked { get; set; }

[JsonProperty(PropertyName = "Block teleport when combat blocked")]
public bool CombatBlocked { get; set; }

[JsonProperty(PropertyName = "Disable respawn options when raid blocked")]
public bool RaidBlockedRespawn { get; set; }

[JsonProperty(PropertyName = "Disable respawn options when combat blocked")]
public bool CombatBlockedRespawn { get; set; }
}

public VersionNumber Version { get; set; }
}

protected override void LoadConfig()
{
base.LoadConfig();
configData = Config.ReadObject<ConfigData>();

if (configData.Version < Version)
UpdateConfigValues();

Config.WriteObject(configData, true);
}

protected override void LoadDefaultConfig() => configData = GetBaseConfig();

private ConfigData GetBaseConfig()
{
return new ConfigData
{
NoEscape = new ConfigData.NoEscapeOptions
{
CombatBlocked = true,
RaidBlocked = true,
CombatBlockedRespawn = true,
RaidBlockedRespawn = true,
},
Teleport = new ConfigData.TeleportOptions
{
BuildingBlocked = true,
BanditCommand = "bandit",
CancelCommand = "canceltp",
Cooldown = 300,
Hostile = true,
OutpostCommand = "outpost",
Wait = 10,
VIPTimes = new Dictionary<string, ConfigData.TeleportOptions.VIP>
{
["compoundteleport.vip1"] = new ConfigData.TeleportOptions.VIP { Cooldown = 150, Wait = 5 },
["compoundteleport.vip2"] = new ConfigData.TeleportOptions.VIP { Cooldown = 30, Wait = 3 },
}
},
Respawn = new ConfigData.RespawnOptions
{
Cooldown = 300,
ForceTo = "None",
AllowBandit = true,
AllowOutpost = true
},
Custom = new List<ConfigData.CustomSpawnPoint>
{
new ConfigData.CustomSpawnPoint
{
Name = "Example1",
Enabled = false,
CanTeleportTo = true,
CanRespawnAt = true,
WorldPosition = new Vector3(0, 0, 0),
Radius = 50,
RaycastTargets = new string[]{"road", "carpark", "pavement", "walkway"}
},
new ConfigData.CustomSpawnPoint
{
Name = "Example2",
Enabled = false,
CanTeleportTo = true,
CanRespawnAt = true,
WorldPosition = new Vector3(0, 0, 0),
Radius = 50,
RaycastTargets = new string[]{"road", "carpark", "pavement", "walkway"}
}
},
Version = Version
};
}

protected override void SaveConfig() => Config.WriteObject(configData, true);

private void UpdateConfigValues()
{
PrintWarning("Config update detected! Updating config values...");

ConfigData baseConfig = GetBaseConfig();

if (configData.Version < new VersionNumber(2, 0, 0))
configData = baseConfig;

if (configData.Version < new VersionNumber(2, 0, 6))
{
configData.NoEscape = baseConfig.NoEscape;
}

if (configData.Version < new VersionNumber(2, 0, 7))
configData.Teleport.VIPTimes = baseConfig.Teleport.VIPTimes;

if (configData.Version < new VersionNumber(2, 0, 16))
configData.Custom = baseConfig.Custom;

configData.Version = Version;
PrintWarning("Config update completed!");
}
#endregion

#region Data
private class Cooldown
{
public int respawn;
public int command;
}
#endregion

#region Localization
private string msg(string key, ulong playerId = 0UL) => lang.GetMessage(key, this, playerId != 0UL ? playerId.ToString() : null);

private Dictionary<string, string> Messages = new Dictionary<string, string>
{
["Name.Outpost"] = "Outpost",
["Name.Bandit"] = "Bandit Camp",
["Error.NoPermission"] = "You do not have permission to use this command",
["Error.TPPending"] = "You already have a teleport pending",
["Error.Hostile"] = "You can not teleport whilst you are marked hostile",
["Error.Cooldown"] = "You must wait another <color=#ce422b>{0}</color> before teleporting again",
["Error.RaidBlocked"] = "You can not teleport while <color=#ce422b>raid blocked</color>!",
["Error.CombatBlocked"] = "You can not teleport while <color=#ce422b>combat blocked</color>!",
["Error.BuildingBlocked"] = "You can not teleport while <color=#ce422b>building blocked</color>!",
["Notification.TPPending"] = "Teleporting to <color=#ce422b>{0}</color> in <color=#ce422b>{1}</color>",
["Notification.NonePending"] = "You do not have any teleports pending",
["Notification.Cancelled"] = "Cancelled pending teleports",
["Notification.NoAreas"] = "No custom spawn areas have been setup",
["Notification.NoAreaWithName"] = "No spawn area found with the name : {0}",
["Notification.NoAreaSpecified"] = "No area specified"
};
#endregion
}
}
удали телепортацию оставь спавн
 
Активность
Пока никто не печатает сообщение