Как и обещал выкладываю код и небольшой гайд
Собственно речь о функции загрузки UID и координат из файла в массив m_playersSpawnPoints класса миссии, который в последствии можно исполдьзовать в других функциях в классе миссии
Отступление
массив m_playersSpawnPoints это массив типа map
В данном случае <string,string> где и индекс и значение текстовые строки
индексом выступает записанный UID, а значением координаты, которые перед использованием преобразуются из текста в vector c помощью функции ToVector()
Но об этом позже
Раздел 1. Подключение
КОд функции:
//Players personal spawn points (for new connected players)
ref map<string,string> m_playersSpawnPoints = new map<string,string>;
void LoadPlayersSpawnPoints()
{
/*
Файл playersSpawnPoints.lst кладем в папку указанную в параметре запуска сервера -profiles= тогда путь будет "$Profile:"
или если кладем в файл в mpmissions\dayzOffline.chernarusplus\_CONF путь будет "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_CONF\\"
Путь меняется в переменной m_SettingsPath - "$Profile:" или "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_CONF\\"
Можете указать свой путь, но он должен быть либо в $Profiles: либо в $CurrentDir:\\mpmissions\\dayzOffline.chernarusplus
Формат файла:
Steam UID в привычном виде 17 цифр Координаты Комментарий (через пробелы)
Помните любая ошибка может привести к крашу сервера
Не желательны пустые строки!
Пример:
76562298156537008 1300 0 5600 Дима
76561998116927209 3000 0 3000 Вася из Новороссийска
Про массив: ref map<string, string> m_playersSpawnPoints = new map<string, string>;
m_playersSpawnPoints тут массив типа map, где каждый элемент массива состоит из 2х ячеек.
1. Индекс - тип string
2. Значение - тип string
Пример работы с массивом типа map
Запись в массив
m_playersSpawnPoints.Insert("76562298156537008", "1300 0 5600"); //записываем первый элемент - индекс dayz, значение 10
m_playersSpawnPoints.Insert("76561998116927209", "3000 0 3000"); //записываем второй элемент - индекс dayzf, значение 17
Чтение из массива:
Получаем значение 0го элемента
string m = m_playersSpawnPoints.GetElement(0); // = "1300 0 5600"
Получаем индекс 0го элемента
string name = m_playersSpawnPoints.GetKey(0); / /= "76562298156537008"
Получаем значение по индексу (в данном случае нас интерисует именно ЭТО)
string n = m_playersSpawnPoints.Get("76561998116927209"); // = "3000 0 3000" //затем n переводим в вектор
Usage in CreateCharacter function for change default spawn position:
string PlayerUID = identity.GetPlainId();
if (PlayerUID)
{
if (m_playersSpawnPoints.Contains(PlayerUID)
{
pos = m_playersSpawnPoints.Get(PlayerUID).ToVector();
}
}
*/
string FileName = "playersSpawnPoints.lst";
string m_SettingsPath = "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_CONF\\"; //Folder with config files - .ini or .lst // Or "$Profiles:\\"
FileHandle file;
string file_line;
array<string> read_line;
int linecount = 0;
//Comments check
bool skipline = false;
bool skipblock = false;
//Comments check
file = OpenFile(m_SettingsPath + FileName, FileMode.READ);
if (file != 0)
{
Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read File: " + m_SettingsPath + FileName + " :::");
while (FGets(file, file_line) >= 0)
{
linecount++;
//Comments check and skip
if (file_line.IndexOfFrom(0,"//") == 0 || file_line.IndexOfFrom(0,"#") == 0 || file_line.IndexOfFrom(0," ") == 0 || file_line.Length() <= 0)
{
skipline = true;
}
else
{
skipline = false;
}
if (file_line.IndexOfFrom(0,"/*") == 0)
{
skipblock = true;
}
else if (file_line.IndexOfFrom(0,"*/") == 0)
{
skipblock = false;
skipline = true;
}
//Comments check
if (!skipline && !skipblock)
{
read_line = new array<string>;
file_line.Split(" ",read_line);
if (read_line.Count() >= 4)
{
if (read_line.Get(0).Length() == 17)
{
if (read_line.Get(1).ToFloat() > 0 && read_line.Get(3).ToFloat() > 0)
{
if (!m_playersSpawnPoints.Contains(read_line.Get(0)))
{
m_playersSpawnPoints.Insert(read_line.Get(0), read_line.Get(1) + " " + read_line.Get(2) + " " + read_line.Get(3)); // UID, Position
Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " Add UID " + read_line.Get(0) + " spawnpoint: " + read_line.Get(1) + " " + read_line.Get(2) + " " + read_line.Get(3) + " to m_playersSpawnPoints");
}
else
{
Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " UID " + read_line.Get(0) + " duplicated, check file!");
}
}
else
{
Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " Position error: '" + read_line.Get(1) + " " + read_line.Get(2) + " " + read_line.Get(3) + "' :::");
}
}
else
{
Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " UID error: " + file_line + " :::");
}
}
else
{
Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " have errors: " + file_line + " :::");
}
}
}
CloseFile(file);
if (m_playersSpawnPoints.Count() > 0)
{
Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Players personal spawn points count: " + m_playersSpawnPoints.Count() + " :::");
}
else
{
Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Players personal spawn points is not loaded! :::");
}
}
else
{
Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Error open file: " + m_SettingsPath + FileName + " :::");
}
}
Комментарии, а так же диагностические принты в лог не убираю сознательно
ПОдключение и использование.
Функцию размещаем в теле класса миссии в init.c или если она вынесена в другой файл (и файл подключени через #include) в том самом файле в теле класса миссии
Вот как-то так:
class CustomMission : MissionServer
{
//Тут разные функции и определение переменных класса...
//Вот тут переопределенный штатно OnInit
override void OnInit ()
{
//тут его код
)
//Тут определяем наш массив и функцию
//Players personal spawn points (for new connected players)
ref map<string,string> m_playersSpawnPoints = new map<string,string>;
void LoadPlayersSpawnPoints()
{
//тут ее код
}
//Тут разные функции...
}
Ну Вы поняли...
Далее нам надо при запуске и инициализации сервера эту функцию выполнить
Но прежде надо создать файл по нужному пути в котором будут UID'ы и координаты
В данной редакции используется путь "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_CONF\\" и имя файла "playersSpawnPoints.lst"
те в папке mpmissions\dayzOffline.chernarusplus нужно создать папку _CONF и поместить в нее этот файл
Но вы можете это переделать как Вам больше нравится
Формат файла:
6561198156925007 2698.36 0 5989.59 USER
6561198156924007 2698.36 0 5989.59 ВАСЯ
6561198156923007 2698.36 0 5989.59 ПЕТЯ
//Тут комментарий
/*
6561193356923001 3698.36 30 5189.59 ПЕТЯ
*/
//Тут комментарий
#Тут комментарий
Первое поле - позиция - Это Steam UID (17 цифирь)
2,3,4 поля позиции числа это координаты X Z Y (Z = высота) - если 0 система поставит перса на землю или ближайшую твердую поверхность под ним
все что дальше игнорится
Можно каментить строки с помощью // , #
Можно каментить блоки
/*
*/
Если первый символ в строке пробел, все остальное то же игнорится
Пустые строки то же игнорятся
Если в строке с UID и координатами ошибка об этом напишет в лог с указанием номера строки
Если UID дублируется об этом то же напишет в лог
Ок
Файл создали
Теперь добавим вызов этой функции в тело функции OnInit в классе миссии (про нее речь шла Выше)
Функция OnInit ВСЕГДА выполняется при запуске сервера
Внутрь мы добавим вызов LoadPlayersSpawnPoints()
В итоге при запуске сервера LoadPlayersSpawnPoints() выполнется и запишет в массив m_playersSpawnPoints UID'ы и координат
Добавляем как-то так:
override void OnInit()
{
//Тут может быть различный код
//Тут вызов нашей функции
//Load players personal spawn poins
LoadPlayersSpawnPoints(); // => m_playersSpawnPoints // "UID", "Position"
//Тут может быть различный код
}
Запустили сервер и увидели в логе что файл прочитался и все ок
.... LoadPlayersSpawnPoints() ::: Players personal spawn points count: итд итп
Или ошибки
Если ошибки - читаем все еще раз и/или задаем вопросы в теме (НЕ В ЛИЧКЕ!!!) показывая что куда и как Вы прописали
Отлично
Тормозим в сервер
Продолжение следует минут через 15