Интернет. Настройки. Тарифы. Телефон. Услуги

Создание мод-сервера Rust на своем компьютере. Создание мод-сервера Rust на своем компьютере Пример считывания данных из файла

Оптимизация игры Rust просто «никчемная», что создает некие трудности во время игрового процесса для некоторых юзеров. В некоторых случаях даже мощный компьютер не в силах справиться со своими прямыми обязанностями, а именно обеспечить отличную картинку без лагов в интерфейсе «ржавчины». Конечно же, благодаря некоторым манипуляциям можно слегка повысить fps в игре, но сделать это получается лучше всего посредством ввода в консольную строку различного рода команд, отключающих специфические эффекты. Но как вы это себе представляете? Каждый раз во время подсоединения к серверу вбивать в консоль около 30 команд – это сколько же времени будет потрачено впустую… Но выход есть и это – файл конфиг для Rust, в который можно вписать все эти команды, а его просто вложить в специальную директорию.

Но где же взять этот cfg для Rust? На самом деле есть два способа его заполучить. Вы можете поступить следующим образом...

Создаем конфиг для игры Rust

1. Зайти в корневой каталог игры.
2. Отыскать там папку CFG.
3. В ней найти два файла: client.cfg и config.cfg.
4. Если их нет, то просто нужно создать новые и соответствующе их назвать.
5. Вписать сюда соответствующие команды для , теней, ветра и так далее.

А можно сделать и по-другому.

Скачать cfg для игры

1. Вы можете скачать конфиг для Rust уже в готовом виде (со всеми нужными командами) прямо с нашего сайта, по этой .
2. Скопировать два файла, находящиеся в архиве в соответствующий каталог (указан в первом способе).
3. Если там уже имеются эти файлы, то копируем с заменой, если нет – то просто вставляем.

По сути, неважно, по какому именно пути вы пойдете. После этого остается лишь:

Зайти в игру
Кликнуть по вкладке «Options»
Убрать отметки с «Water Reflectins» и «VSync»
И полностью оттянуть ползунок «Render Quality» влево

Нужно отметить, что на конфиг для Rust влияет очень положительно, можно даже сказать, что конфиг в Rust (конечно же, правильно настроенный) принесет намного больше пользы, чем дополнительные 512 Мб видеопамяти.

В предыдущих статьях цикла был сделан общий обзор языка программирования Rust, обсуждались основы синтаксиса: были описаны простейшие компоненты (переменные, простые типы данных, операторы и расширения), управляющие конструкции и составные структуры данных, функции и деструкторы. Особое внимание было уделено модели памяти в целом, концепции владения объектами, общим принципам управления памятью, использованию собственных и управляемых блоков общей памяти, а также заимствованных указателей. В данной статье рассматриваются средства ввода/вывода языка Rust.

В любом языке программирования подсистема ввода/вывода является важной составной частью. Некоторые простейшие средства работы со стандартным потоком вывода уже использовались в предыдущих статьях (print , println). Эти функции интуитивно понятны, и не вызывают каких-либо затруднений в процессе их применения. Поэтому сейчас речь пойдёт главным образом о средствах приёма данных, вводимых пользователем и об инструментах работы с файлами.

1. Модуль std::io

В Rust все средства ввода/вывода собраны в модуле io .

В трэйтах (trait) Reader и Writer определён минимальный набор самых простых методов ввода и вывода. Трэйты ReaderUtil и WriterUtil предлагают более широкий выбор методов, предоставляющих пользователю расширенные возможности управления вводом и выводом. Например, Reader позволяет лишь считывать заданное количество байтов в буфер, в то время как в ReaderUtil предлагаются методы считывания целой строки, нескольких строк, числовых значений и т.д. Кроме того, имеется реализация (implementation) ReaderUtil для , которая позволяет получить доступ ко всем методам Reader .

Трэйт (trait) описывает набор методов, которые могут быть применены к определённому типу или к нескольким типам. Более подробно трэйты будут рассматриваться в следующих статьях данного цикла.

Как уже было сказано выше, наиболее часто используемые функции print() и println() также определены в модуле io , но их явное импортирование в большинстве случаев не требуется, так как об этом уже позаботилась система компиляции и связывания.

Кроме того, здесь же определяются весьма полезные функции stdin() , stdout() и stderr() , возвращающие указатели на три стандартных дескриптора файлов: стандартный ввод, стандартный вывод и стандартный поток ошибок соответственно.

2. Получение данных от пользователя

В любом случае самым простым способом получения данных от пользователя является использование функции stdin() , создающей указатель на объект @Reader , что позволяет считывать данные из потока стандартного ввода (аналогичные функции существуют и для стандартного потока вывода - stdout() , а также для стандартного потока ошибок - stderr()). После создания указателя @Reader можно воспользоваться функцией read_line() для чтения строки, вводимой пользователем, как показано в листинге 1.

Листинг 1. Считывание данных, вводимых пользователем
fn main() { let stdin = std::io::stdin(); print("Как Вас зовут? "); let name_str = stdin.read_line(); println(fmt!("Очень приятно познакомиться, %s\n", name_str)); }

В трэйте ReaderUtil помимо простых функций чтения байтов и одиночных строк также определён богатый набор инструментов для считывания данных при различных условиях: считывание байтов до тех пор, пока не встретится признак конца файла - read_until() , считывание строки, записанной в C-стиле (с нулевым завершающим символом), - read_c_str() , считывание всего потока данных целиком - read_whole_stream() , считывание всех строк из потока данных - read_lines() , а также большой набор функций, позволяющих считывать числовые значения, как целые, так и с плавающей точкой.

3. Считывание данных из файла

Все необходимые инструменты для работы с файлами также располагаются в модуле std::io . Прежде всего следует обратить внимание на следующие функции:

fn FILE_reader(f: *libc::FILE, cleanup: bool) -> @Reader fn FILE_writer(f: *libc::FILE, cleanup: bool) -> @Writer fn file_reader(path: &Path) -> Result<@Reader, ~str> fn file_writer(path: &Path, flags: &) -> Result<@Writer, ~str> fn mk_file_writer(path: &Path, flags: &) -> Result<@Writer, ~str>

Варианты FILE_* читают и записывают файлы в C-стиле, тогда как варианты file_* предназначены для использования именно в стиле Rust. Поскольку первые две функции очевидно исполняют роль вспомогательных инструментов для специфических задач, а кроме того всё-таки рассматривается именно язык Rust, предпочтение следует отдать Rust-стилю. Поэтому далее рассматриваться будут только функции file_reader и file_writer . Обе функции в качестве первого параметра принимают путь к файлу, имеющий тип ~str , и обе возвращают значение типа Result . Таким образом, чтобы понять операции файлового ввода/вывода в Rust, необходимо также правильно понимать и оценивать тип Result .

3.1. Тип возвращаемого значения Result

Этот тип служит в Rust средством, позволяющим избежать ошибок времени выполнения. Result - это перечисление, содержащее следующие значения (см. src/libstd/result.rs ):

pub enum Result { Ok(T), /// содержит значение при успешном возврате из функции Err(U) /// содержит значение при ошибке возврата из функции }

Значения типа Result обязательно должны быть распакованы (деструктуризованы) перед их использованием.

В примере программы будет использоваться следующая функция из модуля std::result :

fn unwrap(res: Result) -> T

Если получен результат Ok(T) , то функция возвращает значение T , извлечённое из Ok(T) , которое может использоваться далее в программе.

Разумеется, этой функцией набор инструментария библиотеки std::result не ограничивается. Описания других функций можно найти в указанной выше документации.

3.2. Пример считывания данных из файла

Исходный код примера приведён в листинге 2. В примере просто считываются байты из заданного файла, затем результат чтения преобразовывается в строку и выполняется сравнение с образцом. Предполагается, что сама программа и тестовый файл read.txt , из которого считываются данные, находятся в одном и том же каталоге.

Листинг 2. Побайтовое чтение данных из файла.
use std::io::*; use std::vec::*; use std::path::*; fn is_success(fpath: &PosixPath) { let maybe_test_reader: Result<@Reader, ~str> = file_reader(fpath); let test_reader: @Reader = std::result::unwrap(maybe_test_reader); let mut bytes: ~ = ~; loop { let byte: int = test_reader.read_byte(); if test_reader.eof() { break; } append_one(bytes, byte as u8); } let sample: ~str = ~"success"; let maybe_success: ~str = std::str::from_bytes(bytes); if maybe_success == sample { println("Операция чтения из файла завершилась успешно"); } } fn main() { let fpath: ~PosixPath = ~PosixPath("./read.txt"); is_success(fpath); }

В приведённом выше примере тестовая функция is_success() создаёт объект test_reader , используя переданный ей путь к файлу. Для большей наглядности содержимое файла считывается по одному байту за раз, и считанный байт добавляется в вектор bytes . Байты считываются как целые значения типа int , но при вставке очередного байта в вектор ожидается значение типа u8 . Поэтому для каждого вставляемого байта выполняется явное преобразование as u8 . Эти операции продолжаются до тех пор, пока при считывании не встретится конец файла (end of file).

Метод reader.eof() возвращает true , когда текущий считанный байт содержит признак eof . В этом случае значение этого байта равно -1 (именно это является причиной того, что reader.read_byte() возвращает int , а не u8), и его не нужно добавлять в вектор. Проверяется условие, и если обнаружен EOF , то происходит выход из цикла.

Проверка правильности результата считывания основывается на том факте, что считанные байты представляют собой ASCII-значения (следовательно, совпадают с соответствующей частью кодировки UTF8), то есть, символы, составляющие слово "success".

3.3. Почему не цикл while

При рассмотрении кода в листинге 2 может возникнуть резонный вопрос: почему выполняется выход из цикла с помощью проверки на eof в теле цикла, а не используется более распространённая проверка условия перед очередной итерацией? Причина в том, как работает reader.eof() . При использовании цикла while с проверкой на eof в условном выражении EOF-байт с значением -1 (255u8) добавляется в целевой вектор. Поэтому при использовании while приходится "выталкивать" самое последнее значение из вектора, как показано в листинге 3.

Листинг 3. Фрагмент считывания байтов с использованием цикла while
let mut bytes: ~ = ~; while !reader.eof() { std::vec::append_one(bytes, reader.read_byte() as u8); } std::vec::pop(bytes);

Разумеется, и такой вариант обработки данных имеет право на существование.

Заключение

В языке Rust практически все средства ввода/вывода сконцентрированы в модуле std::io . Для каждого элементарного типа данных предусмотрены инструменты его считывания и представления при выводе. Основными компонентами модуля std::io являются трэйты Reader , Writer , ReaderUtil и WriterUtil , предоставляющие все необходимые возможности управления вводом и выводом данных.


В этой теме я расскажу, как создать свой сервер Rust Experimental с модами. Зачем это надо? Ну, как минимум, если вы играете в Раст, то у вас появляется множество идей, которые гораздо удобней тестить на своем сервере с бесконечными ресурсами и возможностью летать. А если пойти дальше, то вы cможете сделать свой сервер популярным и получать реальные деньги за продажу игровых плюшек игрокам своего сервера.

Итак, приступим.
Часть первая - Создание сервера.
1. Скачать архив Rust_server.zip с официального сайта по этой
2. Распаковать архив в удобную вам папку. Например, вот в эту: C:\Games\Rust_Server\Server
Далее я буду приводить примеры адреса с этой папкой.
3. Зайти в папку C:\Games\Rust_Server\Server и запустить файл update.bat
Откроется черное окошко с командной строкой и в нем пойдет закачка файлов сервера, размер около 2,15 Гб. По окончании загрузки окошко закроется автоматически.
4. Зайти в папку C:\Games\Rust_Server\Server\rustds
Создать текстовый документ в блокноте, скопировать внутрь вот этот текст:
RustDedicated.exe -batchmode -server.hostname "My Server" -server.port 28015 -server.identity Hello_World -server.maxplayers 5 -server.seed 777 -server.worldsize 4000 -chat.serverlog 1 -server.netlog 1 -server.saveinterval 300 -spawn.max_rate 1 -spawn.max_density 1
Далее в блокноте нажимаем "Сохранить как..." и сохраняем файл с именем "start server.bat" расширение "Все файлы".
Появившийся файлик "start server.bat" и есть пусковый файл для вашего сервера. При нажатии на него откроется снова черное окошко командной строки и пойдет создание карты и запуск сервера. О том, что сервер готов к работе, можно узнать, глядя на счетчик фпс справа-внизу окошка: при загрузке он будет показывать 0 fps, а после окончания появится цифровое значение, например у меня это 262 fps.
5. Далее нужно узнать свой внешний IP-адрес.
Допустим, вы зашли на один из сервисом определения IP адреса, и ваш адрес оказался 213.180.193.11
Открываем Rust и жмем кнопку F1, в открывшейся консоли вводим команду client.connect 213.180.193.11:28015

Если все сделано верно, то пойдет подключение и вы окажетесь на своем собственном сервере

P.S.: Папка с файлами вашего сервера (сейв и тд) будет находиться по адресу C:\Games\Rust_Server\Server\rustds\server\Hello_World

Часть вторая: Админка

1. Чтобы сделать себя (или друга) админом на своем сервере, вам сперва нужно узнать свой стим-айди. Для этого заходим в свой профиль в стиме и на любом свободном месте - например, слева от своей аватарки, нажимаем правой кнопкой мышки и выбираем "Скопировать адрес страницы". Вставляем этот адрес куда угодно, например в блокнот или в браузер. Появится что-то вроде }