Лотерея

diller110

Добрая душа
Сообщения
353
Реакции
278
Доброе время суток, хотел создать плагин лотереи, а точнее проапгрейдить существующий. А именно, вывод случайного числа через Hint сообщения на CS GO. upd: Плагин работает, я прошу помощи с возможными утечками и советов оптимизации.
Вот исходник: Посмотреть вложение ac-luck.sp

Сразу несколько вопросов:
1. В начале раунда в хинт пишет типо Play!, и перебивает надпись лотереи. Многие другие плагины тоже перебивают, как их можно отключить на время рандоминга?
 
Последнее редактирование:

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
прошу помощи с возможными утечками и советов оптимизации
PHP:
new String:Primary[36];
Разве decl уже отменили? Используй его.
PHP:
g_Lottery[GetClientOfUserId(GetClientUserId(client))] = 0;
Что за придумки, когда есть сам client?! Он же в обратном вызове консольной команды присутствует.
PHP:
GetCurrentMap(mapname, 30);
Каждый раунд получать карту? Сохраняй разово в OnMapStart(), например.
C-подобный:
for (new i = 0; i<(MAXPLAYERS[B]+1[/B]); i++)
Уж лучше со знаком равно, чем каждый раз прибавлять единичку. А ещё лучше использовать MaxClients - это, в большинстве случаев-серверов, значительно уменьшит цикл. Вряд ли неполный цикл здесь будет создавать сбои в работе плагина (это, как минимум, нужен другой плагин, который меняет количество слотов сервера во время его работы).
PHP:
if (StrContains(mapname, "de_", true) != -1) mapDeType = true;
else mapDeType = false;
Можно попробовать заменить на новом SM:
PHP:
mapDeType = bool:(StrContains(mapname, "de_", true) != -1);
или хотя бы:
PHP:
mapDeType = StrContains(mapname, "de_", true) != -1 ? true:false;
С таймером явно заморочено. Например, пытаешься получить Float значение, когда ничего не сохранял для первого вызова таймера. А amount мог прибавлять в массиве g_Lottery, ведь всё равно туда ничего не пишется, кроме 0 и 1, т.е. там вообще bool бы хватило.
Я конечно подозреваю, что там может писаться цифра для Weapon_names, например, но пока всё смутно.
и перебивает надпись лотереи
Другие плагины тоже можно перебивать повторяющимся таймером, но не стоит.
 

diller110

Добрая душа
Сообщения
353
Реакции
278
Как думаете компилятор так и примет перечисления в штык? Case в любом случае оставлю, т.к. конструкция if else крайне неудобна в данной ситуации. Просто интересно как это повлияет на быстродействие.
PHP:
	switch(Random){
		case 0,1,2,3,4,5,6:{
			if (Client_GetWeaponBySlot(client, 1) != -1) SDKHooks_DropWeapon(client, Client_GetWeaponBySlot(client, 1));
			GivePlayerItem(client, Weapon_names[Random]);
			CGOPrintToChatAll("{LIME}[{LIGHTGREEN}AC{LIME}] {LIGHTOLIVE}%N {GRAY}выйграл {DEFAULT}%s{GRAY}! Попробуй и ты: /luck", client, Weapon_names_translated[Random]);
		}
		case 7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28:{			
			if (Client_GetWeaponBySlot(client, 0) != -1) SDKHooks_DropWeapon(client, Client_GetWeaponBySlot(client, 0));
			CGOPrintToChatAll("{LIME}[{LIGHTGREEN}AC{LIME}] {LIGHTOLIVE}%N {GRAY}выйграл {DEFAULT}%s{GRAY}! Попробуй и ты: /luck", client, Weapon_names_translated[Random]);
			GivePlayerItem(client, Weapon_names[Random]);
		}
		case 29,30,31,32,33,34,35,36:{
			GivePlayerItem(client, Weapon_names[Random]);
			CGOPrintToChatAll("{LIME}[{LIGHTGREEN}AC{LIME}] {LIGHTOLIVE}%N {GRAY}выйграл {DEFAULT}%s{GRAY}! Попробуй и ты: /luck", client, Weapon_names_translated[Random]);
		}
		default:{
			CGOPrintToChat(client, "{LIME}[{LIGHTGREEN}Rank{LIME}] {LIGHTOLIVE}Похоже вам попался приз-пустышка. Ничего, еще повезёт)");	
		}
	}
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
компилятор так и примет перечисления в штык?
Примет. Для него ты всё правильно делаешь, а оптимальность - забота самого скриптера. Оффтоп
 

diller110

Добрая душа
Сообщения
353
Реакции
278
AlmazON, Спасибо, почти все замечания исправил. Решил добавить одну фичу, но столкнулся с непонятной мне логикой:
PHP:
 if(args>0){
				char c_arg[3]; int arg;
				GetCmdArg(2, c_arg, 3);
				PrintToChat(client, "%s", c_arg);
				StringToInt(c_arg, arg);
				if(arg==0) {
					AutoLuck[client] = 0;
					CGOPrintToChat(client, "{LIME}[{LIGHTGREEN}AC{LIME}] {GRAY} Вы отключили автолотерею!");
					return Plugin_Handled;
				} else if(arg>0){
					if (arg > 10) arg = 10;
					AutoLuck[client] = arg;
					CGOPrintToChat(client, "{LIME}[{LIGHTGREEN}AC{LIME}] {GRAY}Вы включили автолотерею на %d раундов!",arg);
					return Plugin_Handled;
				}
				return Plugin_Handled;
			}

Стабильно выполняется кусок кода: if(arg==0) { },
PrintToChat(client, "%s", c_arg); До него не выполняется, как и все остальное.

_____
Update: Ошибку понял, я дурак.
Не StringToInt(c_arg, arg); А agr = StringToInt(c_arg);
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #7
diller110, или
PHP:
arg = StringToInt(c_arg);
Или
PHP:
StringToIntEx(c_arg, arg);
Но не как у тебя
 

diller110

Добрая душа
Сообщения
353
Реакции
278
Между делом, не знаете в чем может быть проблема?
В консоль выдает подобную ошибку:
PHP:
 09/26/2015 - 18:39:32: [SM] Exception reported: Array index is out of bounds
L 09/26/2015 - 18:39:32: [SM] Blaming plugin: webshortcuts_csgo.smx
L 09/26/2015 - 18:39:32: [SM] Call stack trace:
L 09/26/2015 - 18:39:32: [SM]   [1] Line 62, webshortcuts_csgo.sp::OnSay()
L 09/26/2015 - 18:39:32: [SM]   [3] FakeClientCommand
L 09/26/2015 - 18:39:32: [SM]   [4] Line 90, Resetscore+_v1.5.1.sp::LC()

Вот коды на которые указывает:
webshortcuts
PHP:
	new start;
	new len = strlen(text);
	if ( text[len-1] == '"' )  << 62 строка
	{
		text[len-1] = '\0';
		start = 1;
	}
ResetScore+
PHP:
if(t[1] !='\0') FakeClientCommand(C, "%s %s", N, t);

SourceMod девелоперский [01] SourceMod (1.8.0-dev+5666) by AlliedModders LLC. На 1.6 вроде было норм. Что-то связано с новым синтаксисом?
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Известная ошибка. Вызывается, когда идёт отсылка пустого сообщения. Судя по всему, такое удалось отправить через сброс счёта.
Для решения:
C-подобный:
if ( text[len[B]-1[/B]] == '"' )  << 62 строка
len не должно быть равно 0, как бывает. Сделать проверку этого.
 

diller110

Добрая душа
Сообщения
353
Реакции
278
AlmazON, Спасибо, только не очень понял: "Судя по всему, такое удалось отправить через сброс счёта."

И еще немного теории, всегда задавался вопросом насчет этого \0. Как понимаю он равнозначен пустоте. Как в text[len-1] = '\0'; он присваивается? (позиция text - единичная, а "\0" - 2 символа)
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #11
diller110, 0 или '\0' это символ конца строки. Тоесть как только плагин в строке сталкивается с ним он понимает что это конец строки.
это не 2 сивола, \ это экранирование, просто если написать '0' то это будет просто символ нуля
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Пример-эквивалент отправки пустого сообщения от игрока:
PHP:
FakeClientCommand(client, "say ");
Т.е. после пробела должен быть текст, а его нет. Это неправильно, но бывает, а система c len других плагинов этого не учитывает, "устарела".
всегда задавался вопросом насчет этого \0
"Строка ограничивается нулевым символом, или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки.", а также "...очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом..." - это давно описано в доках.
Да, два видимых символа, это строка. Другое дело '\0', о котором и речь.
 

diller110

Добрая душа
Сообщения
353
Реакции
278
AlmazON, R1KO, Спасибо! Поправил webshortcuts, ошибка вроде исчезла.

Еще 1 нюанс, почему в ResetScore if(t[1] !='\0') FakeClientCommand(C, "%s %s", N, t); Проверка 2-ого символа? t[1] !='\0', а не t[0] !='\0'
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755

diller110

Добрая душа
Сообщения
353
Реакции
278
Еще один вопрос:
Задача активация функции путем ввода /tutorial "первые 4 символа ника". Т.е. с моим ником diller110 - !tutorial dill.
Вот что сделал я:
PHP:
            char arges[4][16]; // Создаст 4 буфера, не помню зачем 4, наверно на всякий.
			ExplodeString(Text, " ", arges, 4, 16);   // Делит введенную команду по 4 переменным.
			
			if(strlen(arges[2]) > 0 || strlen(arges[3]) > 0)  // Если 2 или 3 аргументы не пусты, значит ошибка т.к. должно быть только 1.
			{
				CGOPrintToChat(client, "{GRAY}[{LIGHTBLUE}AC{GRAY}] Ошибка при подтверждении прохождения обучения. Введите правильный код из обучения.");
				return Plugin_Handled;
			}
			GetClientName(client, arges[2], 5);  //Получает имя игрока и записывает во 2 буффер (т.к. он свободен)
			if(strlen(arges[1])>0 && StrEqual(arges[1], arges[2], false))   // Если код введен правильный
			{
//выполняется функция
                        }

А теперь что не так: Если у игрока суперпупер ник, например с такими ๑۩۩๑ символами. Активация не проходит. Логично после GetClientName отсекать все символы не буквы. Но как это делать я не знаю.
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #16

diller110

Добрая душа
Сообщения
353
Реакции
278
AlmazON, Мне чтобы игрокам было понятней. Я с веб-частью не дружу, поэтому приходится выкручиваться вот так: *реклама*Оффтоп*реклама*.

Сейчас попробую написать с проверками IsChar... если честно не догадывался об их существовании.

Как понимаю нужно проверять символ на IsCharUpper и IsCharLower - т.к. символов больших и маленьких не бывает?
 

diller110

Добрая душа
Сообщения
353
Реакции
278
Решил немного полегче сделать, но и тут у меня много вопросов :blush2:
Сначала получил вот это:
0 -
1 -
2 -
3 -
4 -
5 -
6 -
7 -
8 -
9 -
10 -

11 -
12 -
13 -
14 -
15 -
16 -
17 -
18 -
19 -
20 -
21 -
22 -
23 -
24 -
25 -
26 -
27 -
28 -
29 -
30 -
31 -
32 -
33 - !
34 - "
35 - #
36 - $
37 - %
38 - &
39 - '
40 - (
41 - )
42 - *
43 - +
44 - ,
45 - -
46 - .
47 - /
48 - 0
49 - 1
50 - 2
51 - 3
52 - 4
53 - 5
54 - 6
55 - 7
56 - 8
57 - 9
58 - :
59 - ;
60 - <
61 - =
62 - >
63 - ?
64 - @
65 - A
66 - B
67 - C
68 - D
69 - E
70 - F
71 - G
72 - H
73 - I
74 - J
75 - K
76 - L
77 - M
78 - N
79 - O
80 - P
81 - Q
82 - R
83 - S
84 - T
85 - U
86 - V
87 - W
88 - X
89 - Y
90 - Z
91 - [
92 - \
93 - ]
94 - ^
95 - _
96 - `
97 - a
98 - b
99 - c
100 - d
101 - e
102 - f
103 - g
104 - h
105 - i
106 - j
107 - k
108 - l
109 - m
110 - n
111 - o
112 - p
113 - q
114 - r
115 - s
116 - t
117 - u
118 - v
119 - w
120 - x
121 - y
122 - z
123 - {
124 - |
125 - }
126 - ~
127 - 
128 - �
На основании этого написал вот это:
PHP:
public Action Cmd_FourChars(int client, int args){
	char nickname[64], fourchars[4];
	GetClientName(client, nickname, 64);
	int length = strlen(nickname), fourcharscount = 0;
	for (int i = 0; i < length; i++){
		if((nickname[i]>64 && nickname[i]<91 && fourcharscount<4) || (fourcharscount<4 && nickname[i]>96 && nickname[i]<123)) {
			fourchars[fourcharscount++] = nickname[i];
		}
	}
	PrintToChatAll("%N = %s ", client, fourchars);
	return Plugin_Handled;
}
Почему выводит diller110 = dilldiller110 ?

upd: У людей с символами например #$diller110 = dilldiller110 , т.е. сортирует удачно, но почему в конце второй раз ник?
upd2: Когда пишет игрок ๑۩۩๑DiroLヅ команду !fourchars не происходит вообще ничего...... (не админ команда)
 
Последнее редактирование:
Сверху Снизу