Заказать игровой сервер Контакты (заказать плагин/исправить ошибки/другое) Пожертвовать Поиск

[ вход ]
[ последние сообщения ]

  • Страница 2 из 3
  • «
  • 1
  • 2
  • 3
  • »
Действия с Файлами и Папками
GreenBytes Дата: Среда, 08.01.2020, 10:31:43 | Сообщение # 16
Сообщений: 19
Репутация: 0 [ +/- ]
Добрый день, подскажите как открыть файл с курсором в конец, записать информацию и закрыть файл.
 
_wS_ Дата: Среда, 08.01.2020, 11:00:28 | Сообщение # 17
https://sm.alliedmods.net/api/
files
WriteFileLine по идее сразу в конец пишет
 
MrGreen Дата: Вторник, 06.04.2021, 03:04:50 | Сообщение # 18
Сообщений: 21
Репутация: 0 [ +/- ]
Здравствуйте, я много интересного узнал, почитав здесь уроки, много операций с файлами и папками, но мне не попалось создание произвольного файла, а вообще есть такая возможность, создать любой файл при необходимости?
 
_wS_ Дата: Среда, 07.04.2021, 00:14:39 | Сообщение # 19
files.inc

Вот чтение каждой строки файла

Код
File f = OpenFile("cfg/server.cfg", "rt");
if (f)
{
    char s[256];
    while (!f.EndOfFile() && f.ReadLine(s, sizeof(s))) {
        PrintToServer("%s", s);
    }
    delete f;
}


Создание - тот же OpenFile, только с флагом "w". Запись: WriteFile, WriteFileString, WriteFileLine.
 
MrGreen Дата: Четверг, 08.04.2021, 13:54:21 | Сообщение # 20
Сообщений: 21
Репутация: 0 [ +/- ]
Цитата _wS_ ()
Создание - тот же OpenFile, только с флагом "w". Запись: WriteFile, WriteFileString, WriteFileLine.


Спасибо большое! Подскажи, пожалуйста, такой момент, создаю переменную типа int, хочу сделать счетчик раундов, когда происходит событие round_end, он плюсуется на 1, но при окончании первого раунда он выдает 2, а не 1. Я посмотрел, что когда на сервере 0 человек и заходят первые 1х1, то срабатывает событие round_end и начинается игра с 0 раундов и по этому у меня плюсуется 1, я решил присваивать не 0, а -1, правильно ли это?
 
_wS_ Дата: Пятница, 09.04.2021, 02:37:38 | Сообщение # 21
Номер раунда обычно равен GetTeamScore(2) + GetTeamScore(3) + 1. Но нужно учесть некоторые вещи, например, что если будет ничья (нет бомбы/заложников/миссии и время раунда истекло), или смена сторон в соревн режиме и счет обнулится (не помню обнуляется ли он), или какой-то плг изменит счет команд. Твой вариант наверно даже надёжнее, но и там нужно это учитывать + все могут покинуть сервер = раунд снова может стать первым, когда они снова зайдут.

Еще поискать можно в

sm_dump_netprops netprops.txt
sm_dump_datamaps datamaps.txt

Например в csgo есть game_round_end и там m_Score, но не знаю оно ли это.
По ключевым словам искать/тестировать.
Готовой функции, которая четко бы выдавала номер раунда, вроде нет.

Цитата MrGreen ()
Я посмотрел, что когда на сервере 0 человек и заходят первые 1х1, то срабатывает событие round_end и начинается игра с 0 раундов и по этому у меня плюсуется 1, я решил присваивать не 0, а -1, правильно ли это?

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

Код
winner (int) (команда победитель)
reason (int) (причина победы)
message (string) (сообщение)

reason скорее всего совпадает с enum CSRoundEndReason, значения как CSRoundEnd_CTWin, CSRoundEnd_BombDefused и тд (cstrike.inc)
 
MrGreen Дата: Пятница, 09.04.2021, 11:38:41 | Сообщение # 22
Сообщений: 21
Репутация: 0 [ +/- ]
Цитата _wS_ ()
winner (int) (команда победитель)
reason (int) (причина победы)
message (string) (сообщение)


Получается, будет выглядеть примерно так:

Код

public void OnPluginStart()
{
        HookEvent("round_end", Round_End, EventHookMode_PostNoCopy);
}

public Round_End(Handle event, const char[] name, bool dontBroadcast)
{
        int winner = GetEventInt(event, "winner");
        if (winner == 2 || winner == 3)
        {
                g_Round_Counter++;
        }
}
 
_wS_ Дата: Пятница, 09.04.2021, 14:20:19 | Сообщение # 23
Почти.
EventHookMode_PostNoCopy заменить на EventHookMode_Post

Код
public void Round_End(Event event, const char[] name, bool dontBroadcast) {
    switch (event.GetInt("winner")) {
        case 2, 3: {
            g_Round_Counter++;
        }
    }
}


И не забывай в OnMapStart очищать g_Round_Counter (и когда игроков останется <= 1).
Хотя, что если их останется 2 например, но они в одной команде, 1 перезайдет в другую команду, и наверно раунды обнулятся.
Поэтому может стоит сделать так:

Код
public void Round_End(Event event, const char[] name, bool dontBroadcast) {
    switch (event.GetInt("winner")) {
        case 2, 3: {
            g_Round_Counter++;
        }
        default: {
            g_Round_Counter = 1;
        }
    }
}


И код верен, только если не может быть ничьей.
Кст, возможно более правильно будет:

Код
default: {
    if (GetTeamScore(2) < 1 && GetTeamScore(3) < 1) {
        g_Round_Counter = 1; // Счет нулевой, значит скорее всего это первый раунд.
    }
    else
    {
        // Т.к. счет не нулевой, считаем ничью тоже прошедшим раундом.
        // Но есть проблема, если ничья произошла в первом раунде 0-0 :) Так что еще бы и причину сканировать.
        // Посмотри события, связанные с началом игры, по ключевым словам например game, round и тд.
        // Возможно есть более подходящее для определения первого раунда.
        g_Round_Counter++;
    }
}

Еще помню, что CS_GetTeamScore и GetTeamScore могут вести себя по-разному, возможно это было в v34.
 
MrGreen Дата: Пятница, 09.04.2021, 16:16:12 | Сообщение # 24
Сообщений: 21
Репутация: 0 [ +/- ]
Цитата _wS_ ()
Еще помню, что CS_GetTeamScore и GetTeamScore могут вести себя по-разному, возможно это было в v34.


Все время забываю про свитчи)) Я пишу плагин для автоматического голосования за карты, в зависимости от количества игроков, много таких плагинов, но они мало-функциональные, решил сам написать, это мой первый плагин.

Пока вот что получается, как я обрабатываю конец раунда:

 
Shouldercannon Дата: Понедельник, 19.02.2024, 15:28:01 | Сообщение # 25
Сообщений: 21
Репутация: 0 [ +/- ]
Хочу записать в массив полный путь к файлу, но увы не знаю как это сделать. И получаю предупреждение на строке
Код
char szBuffer[MAX_PATH_LENGTH];

warning 217: loose indentation. Не соображу как исправить.
Код
#include <sourcemod>

#define MAX_PATH_LENGTH 128

ArrayList g_hGlobalArray;

public OnPluginStart()
{
    RegConsoleCmd("test", ShowFiles2, "");

    new Handle:dir = OpenDirectory("sound/hit/");
    g_hGlobalArray = new ArrayList(ByteCountToCells(128));
    if (dir != INVALID_HANDLE)
    {
  decl String:Name[MAX_PATH_LENGTH];
  new FileType:type;
  while (ReadDirEntry(dir, Name, MAX_PATH_LENGTH, type))
  {
   if (type == FileType_File)
    g_hGlobalArray.PushString(Name); // Вывести полный путь к файлу вместе с именем файла
  }
  CloseHandle(dir);
    }
}

public Action ShowFiles2(client, args)
{
    int iSize;
    char szBuffer[MAX_PATH_LENGTH]; // warning 217: loose indentatio
    iSize = g_hGlobalArray.Length;
    PrintToServer("Size(GlobalArray) = %i", iSize);
    for (new i = 0; i < iSize; ++i)
    {
        g_hGlobalArray.GetString(i, szBuffer, sizeof(szBuffer));
        PrintToServer("GlobalArray[%i] = '%s'", i, szBuffer);
    }
}
 
_wS_ Дата: Понедельник, 19.02.2024, 16:10:08 | Сообщение # 26
Цитата
warning 217: loose indentation

Это когда внутри функции у строк есть смешанные отступы из пробелов и TAB'ов.

Код
void MyFunc()
{
    строка (начало)
    ...
    строка (конец)
}

1. Выделяем всё, начиная с "строка (начало)" и до (включая) "строка (конец)".
2. SHIFT + TAB и всё сместилось влево на один TAB.
3. Теперь просто TAB и всё сместилось назад.

Теперь все отступы должны быть в виде TAB и ошибки быть не должно. Если отступы сильно кривые и неравномерные, то шаг 2 можно выполнить до упора, чтобы всё прижалось влево, и затем выравнивать отдельные части TAB'ом.

Но часто достаточно подправить отступ лишь в одной строке, на которую жалуется компилятор.
Посмотри, какие отступы в других строках, и используй такие же (пробелы или TAB'ы) в проблемной строке.
 
Shouldercannon Дата: Понедельник, 19.02.2024, 16:47:55 | Сообщение # 27
Сообщений: 21
Репутация: 0 [ +/- ]
Цитата _wS_ ()
Это когда внутри функции у строк есть смешанные отступы из пробелов и TAB'ов.

Действительно. Вот это чувствительность.

В массив можно записать путь к файлу + имя файла одной строкой в
Код
while (ReadDirEntry(dir, Name, MAX_PATH_LENGTH, type))

?


Сообщение отредактировал Shouldercannon - Понедельник, 19.02.2024, 16:48:21
 
_wS_ Дата: Понедельник, 19.02.2024, 18:27:04 | Сообщение # 28
Цитата Shouldercannon ()
В массив можно записать путь к файлу + имя файла одной строкой в
while (ReadDirEntry(dir, Name, MAX_PATH_LENGTH, type))

?

ReadDirEntry всегда возвращает просто имя файла или папки.
Если нужен какой-то путь, то используем FormatEx.
 
Shouldercannon Дата: Вторник, 20.02.2024, 10:17:24 | Сообщение # 29
Сообщений: 21
Репутация: 0 [ +/- ]
Код
#include <sourcemod>

#define MAX_PATH_LENGTH 128

ArrayList g_hGlobalArray;

...

public Action ShowFiles(client, args)
{
    new Handle:dir = OpenDirectory("sound/hit/");
    g_hGlobalArray = new ArrayList(ByteCountToCells(128));
    if (dir != INVALID_HANDLE)
    {
  decl String:Name[MAX_PATH_LENGTH];
  new FileType:type;
  char path[PLATFORM_MAX_PATH];  
  while (ReadDirEntry(dir, Name, MAX_PATH_LENGTH, type))
  {
   if (type == FileType_File)
   {
    PrintToServer("[Full path]: %s/%s", dir, Name);
    FormatEx(path, sizeof(path), "%s/%s", dir, Name);
    g_hGlobalArray.PushString(path);
   }
  }
  CloseHandle(dir);
    }
}

На выходе получил:
[Full path]: д/hit1.wav
[Full path]: д/hit2.wav
[Full path]: д/hit3.wav
[Full path]: д/hit4.wav


Сообщение отредактировал Shouldercannon - Вторник, 20.02.2024, 10:20:09
 
_wS_ Дата: Вторник, 20.02.2024, 11:10:49 | Сообщение # 30
Цитата Shouldercannon ()
На выходе получил:
[Full path]: д/hit1.wav

Ну dir это же Handle, а не String/char.

FormatEx(path, sizeof(path), "hit/%s", Name);
PrintToServer("%s", path); // hit/hit1.wav
 
  • Страница 2 из 3
  • «
  • 1
  • 2
  • 3
  • »
Поиск: