Интересует вопрос, как получить последние 10 сообщений игрока в чат? Максимум что у меня вышло, так получить последнее сообщение.
Заранее спасибо.
//DeimoS: Тема почищена от оффтопа и закрыта.
Вид для печати
Интересует вопрос, как получить последние 10 сообщений игрока в чат? Максимум что у меня вышло, так получить последнее сообщение.
Заранее спасибо.
//DeimoS: Тема почищена от оффтопа и закрыта.
У меня скорее всегода так оно и сетьговнокод. Возможно, он и работает :В
PHP код:
public OnPlayerText(playerid, text[])
{
static msg[144 * 10];
new msg_id, if_msg_o10;
strcat(msg, text);
strcat(msg, "\n");//как обозначение конца сообщения
for (new i, j = sizeof(msg); i < j; i++)
{
if (strfind(msg, "\n", true))
{
if_msg_o10 = strfind(msg, "\n", true);
msg_id++;
if (msg_id >= 10)
// предпологается, что если совпадений больше 10,
// то все лишние сообщения удаляться, которые после '\n'
{
strdel(msg, if_msg_o10, sizeof(msg));
break;
}
}
else
{
break;
}
}
return 1;
}
Да я не уверен, будет ли работать :D
А по плану все шло так. Например, игрок в чат ввел "Привет" и в массив запишется "Привет\n", чтобы хоть как-то разделить между собой строки без путаницы. Далше, если игрок введет "Как дела?", то в массиве уже будут "Привет\nКак дела?\n". И так далее. Как только символов '\n' стало больше 10, остальную часть массива удаляем. Ведь суть - 10 сообщений. Мне такой вариант показался вполне адекватным. Лучше бы все это запилить в PVar, но я с ними не очень и признаюсь, запутался в GetPVarString ;D.
Для теста показывайте диалог при каждом вызове каллбэка OnPlayerText, ибо без PVars не оч эффективно выходит. Можно запилить new msg[144 * 10]; как глобальный массив. Но лучше переделать в Pvar.PHP код:
public OnPlayerText(playerid, text[])
{
static msg[144 * 10];
new msg_id, if_msg_o10;
strcat(msg, text);
strcat(msg, "\n");//как обозначение конца сообщения
for (new i, j = sizeof(msg); i < j; i++)
{
if (strfind(msg, "\n", true))
{
if_msg_o10 = strfind(msg, "\n", true);
msg_id++;
if (msg_id >= 10)
// предпологается, что если совпадений больше 10,
// то все лишние сообщения удаляться, которые после '\n'
{
strdel(msg, if_msg_o10, sizeof(msg));
break;
}
}
else
{
break;
}
}
ShowPlayerDialog(playerid, 1, DIALOG_STYLE_MSGBOX, ".", msg, "X", "");
return 1;
}
Ну вот самый простой вариант, что пришёл в голову.
В начало мода
PHP код:
#define NUMBER_STORABLE_LINES 10
new recent_player_messages[MAX_PLAYERS][NUMBER_STORABLE_LINES][144];
В конец мода
И public OnPlayerTextPHP код:
stock ShowRecentPlayerMessage(playerid, targetplayerid)
{
if(!recent_player_messages[targetplayerid][0][0]) return SendClientMessage(playerid, 0xFF0000FF, "Ошибка: {FFFFFF}Данный игрок ещё не написал ни одного сообщения в чат");
new string[144];
SendClientMessage(playerid, -1, "Последние сообщения игрока:");
for(new i; i < NUMBER_STORABLE_LINES; i++)
{
if(!recent_player_messages[targetplayerid][i][0]) break;
format(string, sizeof(string), "%i) %s", i+1, recent_player_messages[targetplayerid][i]);
SendClientMessage(playerid, -1, string);
}
return 1;
}
Показ функцией:PHP код:
public OnPlayerText(playerid, text[])
{
if(!recent_player_messages[playerid][NUMBER_STORABLE_LINES-1][0])
{
for(new i; i < NUMBER_STORABLE_LINES; i++)
{
if(!recent_player_messages[playerid][i][0])
{
format(recent_player_messages[playerid][i], 144, "%s", text);
break;
}
}
}
else
{
for(new i; i < NUMBER_STORABLE_LINES-1; i++) format(recent_player_messages[playerid][i], 144, "%s", recent_player_messages[playerid][i+1]);
format(recent_player_messages[playerid][NUMBER_STORABLE_LINES-1], 144, "%s", text);
}
return 1;
}
В теории всё работает :)PHP код:
ShowRecentPlayerMessage(/*ID того, кому показываем чат игрока*/, /*ID того, чей чат показываем*/);
P.S. У Untonyst задумка интересная. Может что сейчас ещё придумаю... (UPD: Не, лень :D)
Да, почти понял код, но вот этот отрезок не дойдет никак.
PHP код:
else
{
for(new i; i < NUMBER_STORABLE_LINES-1; i++)
{
format(recent_player_messages[playerid][i], 144, "%s", recent_player_messages[playerid][i+1]);
format(recent_player_messages[playerid][NUMBER_STORABLE_LINES-1], 144, "%s", text);
}
}
Если все строки массива заполнены (написано больше 10 сообщений), мы запускаем цикл, который в текущую ячейку массива, прогоняемую циклом, перезаписываем значение следующей ячейки. Тем самым мы удаляем самое первое сообщение из десяти, а все остальные девять сообщений смещаем на строчку выше, освобождая последнюю строку для нового сообщения, тем самым не нарушая хронометрию.
То есть, у нас было записано десять сообщений:
И если игрок напишет, например "Админ - не закон. Я - закон!", то получится так:PHP код:
1) Привет всем
2) Я Алёша
3) Гоу все на мой чудный сервер
4) Каждому по админке
5) И лидерку тоже каждому дам
6) Сервер уникальный
7) Правда мод скачан с паблика
8) И лагает жутко
9) Но вы это узнаете позже
10) Заходите!
А не так:PHP код:
1) Я Алёша
2) Гоу все на мой чудный сервер
3) Каждому по админке
4) И лидерку тоже каждому дам
5) Сервер уникальный
6) Правда мод скачан с паблика
7) И лагает жутко
8) Но вы это узнаете позже
9) Заходите!
10) Админ - не закон. Я - закон! // Вот это сообщение
Только код изменять не стоило, ибо Ваша версия не верна. Цикл должен работать лишь с первой функцией format. Вторая функция должна 1 раз вызываться, в самом конце. Если так нужны скобки, то так будет вернееPHP код:
1) Админ - не закон. Я - закон! // Вот это сообщение
2) Я Алёша
3) Гоу все на мой чудный сервер
4) Каждому по админке
5) И лидерку тоже каждому дам
6) Сервер уникальный
7) Правда мод скачан с паблика
8) И лагает жутко
9) Но вы это узнаете позже
10) Заходите!
PHP код:
else
{
for(new i; i < NUMBER_STORABLE_LINES-1; i++)
{
format(recent_player_messages[playerid][i], 144, "%s", recent_player_messages[playerid][i+1]);
}
format(recent_player_messages[playerid][NUMBER_STORABLE_LINES-1], 144, "%s", text);
}
Самое оптимальное решение: (Вычислительная сложность - O(n))
Также, не забывай обнулить переменную TotalMessages{playerid} в OnPlayerDisconnect.PHP код:
#define LAST_MESSAGE_NUMBER 10
new LastPlayerMessages[MAX_PLAYERS][LAST_MESSAGE_NUMBER][144];
new TotalMessages[MAX_PLAYERS char];
public OnPlayerText(playerid, text[])
{
if TotalMessages{playerid} < LAST_MESSAGE_NUMBER *then strins(LastPlayerMessages[playerid][TotalMessages{playerid}++], text, 0);
else{
format(LastPlayerMessages[playerid][TotalMessages{playerid}++-LAST_MESSAGE_NUMBER], sizeof LastPlayerMessages[][], "%s", text);
if TotalMessages{playerid} >= 2*LAST_MESSAGE_NUMBER *then TotalMessages{playerid} = LAST_MESSAGE_NUMBER;
}
return 0;
}
CMD:showlastmessages(playerid, params[])
{
new _showmess[(4+144)*LAST_MESSAGE_NUMBER];
if sscanf(params, "i", params[0]) *then return SendClientMessage(playerid, COLOR_RED, "Введите: /showlastmessages [id игрока]");
if !TotalMessages{params[0]} *then return SendClientMessage(playerid, COLOR_RED, "Игрок ничего не писал в чат.");
if TotalMessages{params[0]} - 1 < LAST_MESSAGE_NUMBER *then
for new _i = 0; _i < TotalMessages{params[0]}; _i++ do
format(_showmess, sizeof _showmess, "%s\n%i) %s", _showmess, LAST_MESSAGE_NUMBER - _i, LastPlayerMessages[params[0]][_i]);
else{
for new _i = TotalMessages{params[0]} - LAST_MESSAGE_NUMBER; _i < LAST_MESSAGE_NUMBER; _i++ do
format(_showmess, sizeof _showmess, "%s\n%i) %s", _showmess, TotalMessages{params[0]} -_i , LastPlayerMessages[params[0]][_i]);
for new _i = 0; _i < TotalMessages{params[0]} - LAST_MESSAGE_NUMBER; _i++ do
format(_showmess, sizeof _showmess, "%s\n%i) %s", _showmess, TotalMessages{params[0]} - LAST_MESSAGE_NUMBER -_i , LastPlayerMessages[params[0]][_i]);
}
ShowPlayerDialog(playerid, D_NULL, DIALOG_STYLE_MSGBOX,"{CC0000} Последние сообщения:", _showmess, "Хорошо", "");
return 1;
}