Форум Pawn.Wiki - Воплоти мечту в реальность!: помогите с системой управления сервером с сайта - Форум Pawn.Wiki - Воплоти мечту в реальность!

Перейти к содержимому

Страница 1 из 1
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

[ Pawn ]
помогите с системой управления сервером с сайта

#1
Пользователь офлайн   liquidosich 

  • Пользователь
  • Вставить ник
  • Раскрыть информацию
Дратути) Я решил попробовать сделай сайт, который будет выполнять роль панели управления - пока я решил добавить кнопку в панели "Выполнение команд". Как я это решил реализовать? В mysql базе есть таблица server_command как она работает, я на сайте ввожу команду (/rkick nick) в таблицу добавляется команда - сервер каждую секунду проверяет есть ли команды - если команда появляется - выполняет.. Но почему-то когда я все вроде бы подключил (бд как на сервере так и на сайте, все найстроил в моде) когда я отправляю команду на сайте - сервер её не видит, хотя в таблице mysql она появляется (в логах пишет что команды не обнаружено)..

Сайт: https://imgur.com/iSueIHN

Сижу уже 6 час))))) Кто сможет поможет буду очень благодарен. (+ поставлю)

forward CheckServerCommands();
public CheckServerCommands() {
    new query[512];
    format(query, sizeof(query), "SELECT id, command, param FROM server_commands WHERE executed = 0 LIMIT 10");
    if (!mysql_tquery(dbHandle, query, "OnServerCommandResult")) {
        printf("Ошибка выполнения mysql_tquery");
    } else {
        printf("Запрос команд выполняется...");
    }
    return 1;
}
forward OnServerCommandResult(handle, affectedrows, const result[][], error[]);
public OnServerCommandResult(handle, affectedrows, const result[][], error[]) {
    if (error[0] != '\0') {
        printf("[MYSQL ERROR] %s", error);
        return 0;
    }

    if (!result[0][0]) {
        printf("Нет новых команд.");
        return 1;
    }

    for (new i = 0; i < 10; i++) {
        if (!result[i][0]) break;

        new id = strval(result[i][0]);
        new command[64];
        new param[64];
        new cmd[64];

        CopyString(command, result[i][1], sizeof(command));
        CopyString(param, result[i][2], sizeof(param));

        // Убираем слеш, если есть
		if (command[0] == '/') {
		    // копируем строку начиная со второго символа (индекс 1)
		    CopyString(cmd, command[1], sizeof(cmd));
		} else {
		    CopyString(cmd, command, sizeof(cmd));
		}

        printf("Найдена команда ID=%d: %s %s", id, cmd, param);

        if (strcmp(cmd, "rkick", true) == 0) {
            if (KickPlayerByName(param)) {
                printf("Кикнул игрока %s", param);
            } else {
                printf("Игрок %s не найден для кика", param);
            }
        }

        new update_query[128];
        format(update_query, sizeof(update_query), "UPDATE server_commands SET executed=1 WHERE id=%d", id);
        mysql_tquery(dbHandle, update_query, "OnUpdateCommandResult");
    }

    return 1;
}
forward OnUpdateCommandResult(handle, affectedrows, const result[][], error[]);
public OnUpdateCommandResult(handle, affectedrows, const result[][], error[]) {
    if (error[0] != '\0') {
        printf("[MYSQL ERROR] %s", error);
    } else {
        printf("Команда помечена как выполненная.");
    }
    return 1;
}
forward OnServerCommandUpdate(handle, affectedrows, const result[][], error[]);
public OnServerCommandUpdate(handle, affectedrows, const result[][], error[]) {
    if (error[0] != '\0') {
        printf("[MYSQL ERROR при обновлении] %s", error);
    } else {
        printf("Команда помечена как выполненная.");
    }
    return 1;
}

forward KickPlayerByName(const name[]);
public KickPlayerByName(const name[]) {
    new found = 0;
    for (new i = 0; i < MAX_PLAYERS; i++) {
        if (IsPlayerConnected(i)) {
            new playerName[MAX_PLAYER_NAME];
            GetPlayerName(i, playerName, sizeof(playerName));
            printf("Сравнение: '%s' vs '%s'", playerName, name);

            if (strcmp(playerName, name, true) == 0) {
                Kick(i);
                printf("Кикнул игрока %s с ID %d", playerName, i);
                found = 1;
                break;
            }
        }
    }

    if (!found) {
        printf("Игрок с именем %s не найден для кика", name);
    }
    return found;
}

// В GameModeInit проверяет каждую секунду

    SetTimer("CheckServerCommands", 1000, true);
    CheckServerCommands();


CREATE TABLE `server_commands` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `command` VARCHAR(64) NOT NULL,
  `param` VARCHAR(64) NOT NULL,
  `executed` TINYINT(1) NOT NULL DEFAULT 0,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


Сайт (кто шарит в php, html)
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Отправка команды на сервер</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f3f3f3;
            padding: 30px;
        }
        .container {
            background-color: white;
            padding: 25px;
            border-radius: 8px;
            width: 400px;
            margin: auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }
        label {
            font-weight: bold;
        }
        input[type="text"] {
            width: 100%;
            padding: 8px;
            margin-top: 4px;
            margin-bottom: 15px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        input[type="submit"] {
            background-color: #4CAF50;
            color: white;
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .success {
            color: green;
            margin-top: 15px;
        }
        .error {
            color: red;
            margin-top: 15px;
        }
    </style>
</head>
<body>

<div class="container">
    <h2>Отправка команды на сервер SA-MP</h2>
    <form method="post">
        <label for="command">Команда (например, /rkick):</label>
        <input type="text" id="command" name="command" required>

        <label for="param">Параметр (например, Liquidosich):</label>
        <input type="text" id="param" name="param" required>

        <input type="submit" value="Отправить">
    </form>

<?php
// Только если форма отправлена
if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    // Подключение к MySQL
    $host = '(в коде вписано)';
    $user = '(в коде вписано)';
    $password = '(в коде вписано)';
    $database = '(в коде вписано)';

    $mysqli = new mysqli($host, $user, $password, $database);
    if ($mysqli->connect_error) {
        echo "<div class='error'>Ошибка подключения: " . $mysqli->connect_error . "</div>";
        exit;
    }

    // Получаем данные из формы
    $command = trim($_POST['command'] ?? '');
    $param = trim($_POST['param'] ?? '');

    // Убираем слеш в начале команды
    if (strlen($command) > 0 && $command[0] === '/') {
        $command = substr($command, 1);
    }

    // Проверяем, что не пусто
    if ($command === '' || $param === '') {
        echo "<div class='error'>Ошибка: укажите команду и параметр.</div>";
        exit;
    }

    // Вставка в БД
    $stmt = $mysqli->prepare("INSERT INTO server_commands (command, param, executed) VALUES (?, ?, 0)");
    if (!$stmt) {
        echo "<div class='error'>Ошибка подготовки запроса: " . $mysqli->error . "</div>";
        exit;
    }

    $stmt->bind_param("ss", $command, $param);
    if ($stmt->execute()) {
        echo "<div class='success'>Команда успешно добавлена.</div>";
    } else {
        echo "<div class='error'>Ошибка при добавлении команды: " . $stmt->error . "</div>";
    }

    $stmt->close();
    $mysqli->close();
}
?>
</div>

</body>
</html>

Сообщение отредактировал liquidosich: 30 июля 2025 - 00:29

0

#2
Пользователь офлайн   DeimoS 

  • Evil Scripter
  • Вставить ник
  • Раскрыть информацию
Какая-то крайне сомнительная реализация, честно говоря. Уж лучше хотя бы на WebSocket реализовать всё, либо готовый плагин поискав, либо самостоятельно написав. Ну или аналоги поискав, через которые можно будет инфу извне получать.

Ну а по своей проблеме - покажи, как минимум, скрин содержимого таблицы. И ты точно к одной БД цепляешься?
0

#3
Пользователь офлайн   liquidosich 

  • Пользователь
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияDeimoS (30 июля 2025 - 17:07) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]

Да, у меня на все одна бд, вот сама таблица https://imgur.com/hVzVk7k

Сообщение отредактировал liquidosich: 30 июля 2025 - 17:21

0

#4
Пользователь офлайн   DeimoS 

  • Evil Scripter
  • Вставить ник
  • Раскрыть информацию
Удали файл логов MySQL. Далее:
mysql_log(ALL);

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


UPD: А что вообще за обработка такая результата запроса? Какая версия MySQL?

Сообщение отредактировал DeimoS: 30 июля 2025 - 17:31

0

#5
Пользователь офлайн   DeimoS 

  • Evil Scripter
  • Вставить ник
  • Раскрыть информацию
Короче, как-то так. Это для R40+.

const MAX_SERVER_COMMAND_LOAD = 10;

forward CheckServerCommands();
public CheckServerCommands() 
{
    static query[72+11+1];
    if(isnull(query))
    {
        format(query, sizeof(query), "SELECT id, command, param FROM server_commands WHERE executed = 0 LIMIT %d", MAX_SERVER_COMMAND_LOAD );
    }
    mysql_tquery(dbHandle, query, "OnServerCommandResult");
    return 1;
}

forward OnServerCommandResult();
public OnServerCommandResult() 
{
    new row_count;
    cache_get_row_count(row_count);

    if(!row_count)
    {
        printf("Нет новых команд.");
        return 1;
    }

    new ids[MAX_SERVER_COMMAND_LOAD];
    new command[64];
    new param[64];
    
    for(new i = 0; i < row_count; i++) 
    {
        cache_get_value_name_int(i, "id", ids[i]);
        cache_get_value_name(i, "command", command);
        cache_get_value_name(i, "param", param);

        CopyString(command, command, sizeof(command));
        CopyString(param, param, sizeof(param));

        // Убираем слеш, если есть
        if(command[0] == '/') 
        {
           strdel(command, 0, 1);
        }

        printf("Найдена команда ID=%d: %s %s", ids[i], cmd, param);

        if (strcmp(cmd, "rkick", true) == 0) {
            if (KickPlayerByName(param)) {
                printf("Кикнул игрока %s", param);
            } else {
                printf("Игрок %s не найден для кика", param);
            }
        }
    }


    new update_query[47+11+1];
    for(new i = 0; i < row_count; i++)
    {
        format(update_query, sizeof(update_query), "UPDATE server_commands SET executed=1 WHERE id=%d", ids[i]);
        mysql_tquery(dbHandle, update_query);
    }
    return 1;
}


forward KickPlayerByName(const name[]);
public KickPlayerByName(const name[]) 
{
    if(isnull(name))
    {
        return 0;
    }

    new playerName[MAX_PLAYER_NAME];
    for(new i = 0; i < MAX_PLAYERS; i++) 
    {
        if(IsPlayerConnected(i)) 
        {
            GetPlayerName(i, playerName, sizeof(playerName));
            printf("Сравнение: '%s' vs '%s'", playerName, name);

            if(strcmp(playerName, name, true) == 0) 
            {
                Kick(i);
                printf("Кикнул игрока %s с ID %d", playerName, i);
                return 1;
            }
        }
    }
    return 0;
}


Хотя если уж и костылить через БД всё, то лучше существующие команды записать в отдельную таблицу, а в "server_commands" просто ссылаться на эти ID. И в моде команды записать в массив в том же порядке. Тогда ты и в БД будешь только ID хранить, и в мод выгружать будешь ID без нужды делать сверку текста через strcmp. Да и точность введения команды это обеспечит + на сайте можно будет просто всплывающим списком команды выбирать.

Сообщение отредактировал DeimoS: 30 июля 2025 - 17:49

1

#6
Пользователь офлайн   liquidosich 

  • Пользователь
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияDeimoS (30 июля 2025 - 17:48) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]


D:\Revex DM\SAMP SERVER\Mod — копия\gamemodes\revex.pwn(2732) : error 035: argument type mismatch (argument 3)
D:\Revex DM\SAMP SERVER\Mod — копия\gamemodes\revex.pwn(2757) : error 017: undefined symbol "mysql_get_row_data_int"
D:\Revex DM\SAMP SERVER\Mod — копия\gamemodes\revex.pwn(2760) : error 017: undefined symbol "mysql_get_row_data_string"
D:\Revex DM\SAMP SERVER\Mod — копия\gamemodes\revex.pwn(2760) : warning 202: number of arguments does not match definition
D:\Revex DM\SAMP SERVER\Mod — копия\gamemodes\revex.pwn(2763) : error 017: undefined symbol "mysql_get_row_data_string"
D:\Revex DM\SAMP SERVER\Mod — копия\gamemodes\revex.pwn(2763) : warning 202: number of arguments does not match definition
Pawn compiler 3.2.3664 Copyright © 1997-2006, ITB CompuPhase


4 Errors.


у меня R39-6 версия.. Щас под нее адаптирую
0

Поделиться темой:


Страница 1 из 1
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей


Яндекс.Метрика