Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Komunikacja z graczemczyli Jak zacząć Scripting AMXX


  • Nie możesz napisać tematu
  • Zaloguj się, aby dodać odpowiedź
5 odpowiedzi w tym temacie

#1 Gość_21977_*

  • Gość

Reputacja: 0

Offline

Napisano 03.12.2012 20:00

*
Popularny

Tutorial dla początkujących
Komunikacja z graczem
Scripting AMXX


Cel
Nauka podstawowych metod komunikacji gracza z serwerem

Wymagania
  • Informacje wstępne
    Spoiler
  • Zrozumienie istoty działania AMXX
  • Znajomość podstawowych funkcji
  • Umiejętność imptowania bibliotek
  • Zwracanie odpowiedniej wartości funkcji
  • Odczytywanie argumentów wiadomości
Logevents
Jak już wiemy z poprzedniego kursu, funkcja register_event pozwala nam zarejestrować dowolne zdarzenie silnika HLDS.

Jednakże, możemy rejestrować także wystąpienie pewnych wiadomości poprzez funkcję register_logevent
Funkcja register_logevent jednak, jako, że rejestruje jedynie wystąpienie wiadomości, będącej wynikiem
wywołania danej operacji, nie może na tę operację wpływać, a jedynie pozyskać informację o wykonaniu danej operacji.

Pierwszym argumentem funkcji register_event jest nazwa funkcji, wykonywanej w momencie odnotowania danego zdarzenia.
Drugim parametrem jest liczba argumentów, które będziemy odczytywać. W kolejnych, opcjonalnych argumentach, możemy ograniczyć
notowane zdarzenia funkcji filtrami, operując na poszczególnych parametrach, licząc argumenty od 0. Liczba kolejnych
argumentów filtrujących jest dowolna, a niespełnienie choć jednego z nich, nie wywoła funkcji z pierwszego parametru.

Filtry logevents
Do dyspozycji mamy następujące filtry:
  • Równość
    arg=val
    
    Argument nr arg musi być dokładnie taki, jak podana wartość val, np.
    "0=World triggered"
    
  • Nierówność
    arg!val
    
    Argument nr arg nie może zawierać podanej wartości val, np.
    "0!World triggered"
    
  • Większość
    arg>val
    
    Argument nr arg musi być większy, niż podana wartość val, np.
    "1>2"
    
  • Mniejszość
    arg<val
    
    Argument nr arg musi być mniejszy, niż podana wartość val, np.
    "3<4"
    
  • Zawieranie
    arg&val
    
    Argument nr arg musi zawierać wartość val, np.
    "1&spawn"
    
Przykład pełnej funkcji rejestrującej spawn gracza z bombą:
register_logevent("spawnedWithBomb", 3, "1=triggered", "2=Spawned_With_The_Bomb");

Jednakże, co w przypadku, gdy chcielibyśmy zarejestrować zarówno spawn z bombą,
jak i otrzymanie bomby (np. poprzez podniesienie z ziemi) za pomocą register_event?
Jak pamiętamy, funkcja zostanie wywołana, o ile koniunkcja warunków z argumentów opcjonalnych zostanie spełniona.
W przypadku chęci rejestracji otrzymania bomby (czy to przez podniesienie, czy otrzymanie wraz ze spawnem) bowiem,
potrzebujemy alternatywy tych warunków. I na to jest rozwiązanie! Z pomocą przychodzi nam funkcja read_logargv.

read_logargv
Funkcja ta odczytuje zawartość zadanego w pierwszym argumencie, parametru zdarzenia logowanego (licząc od zera)
i zapisuje do tablicy o nazwie z drugiego argumentu o maksymalnym rozmiarze z trzeciego argumentu funkcji read_logargv.
Zobaczmy to na przykładzie:
#include <amxmodx>

public plugin_init(){
register_plugin("Bomb get detect", "0.1", "benio101");

register_logevent("playerTriggered", 3, "1=triggered");
}

public playerTriggered(){
new akcja[64];
read_logargv(2, akcja, 64);

if(
equali(akcja, "Spawned_With_The_Bomb") ||
equali(akcja, "Got_The_Bomb")
){
// Jakis gracz otrzymal bombe
}
}
Rejestrujemy logevent i ograniczamy go jedynie do równości drugiego argumentu z "triggered".
Następnie, w funkcji playerTriggered, pobieramy zawartość trzeciego argumentu do zmiennej akcja.
Jeśli akcją jest otrzymanie bomby lub spawn z bombą, co sprawdzamy w warunku połączonym alternatywą,
to oznacza, że Jakiś gracz otrzymał bombę. Teraz pozostanie nam odczytać jego id i napiszemy mu to.
#include <amxmodx>

public plugin_init(){
register_plugin("Bomb get detect", "0.1", "benio101");

register_logevent("playerTriggered", 3, "1=triggered");
}

public playerTriggered(){
new akcja[64];
read_logargv(2, akcja, 64);

if(
equali(akcja, "Spawned_With_The_Bomb") ||
equali(akcja, "Got_The_Bomb")
){
// Jakis gracz otrzymal bombe

new arg0[64], name[64], argid, id;
read_logargv(0, arg0, 64);

parse_loguser(arg0, name, 64, argid);
id=find_player("k", argid);

client_print(id, print_chat, "Otrzymales bombe!");
}
}
Pobraliśmy tutaj zawartość pierwszego argumentu do zmiennej arg0, następnie pobraliśmy nick gracza za pomocą funkcji parse_loguser,
by na końcu odnaleźć jego właściwe id za pomocą funkcji find_player i wyświetlić mu komunikat o otrzymaniu bomby.

Komunikacja serwera z graczem
Rozgrywka multiplayer na serwerze możliwa jest dzięki komunikowaniu się klientów gry oraz serwera HLDS.
Każde kliknięcie myszy, nachylenie się, czy zmiana pozycji u gracza, a także wywołania jakiejś komendy,
wpływają na informacje przesyłane od klienta do serwera gry. Z drugiej strony, serwer także systematycznie
komunikuje się z nami, przesyłając informacje o naszej pozycji, punktach zdrowia, czy pojawiającym się nowym granacie dymnym i jego lokalizacji.

Podczas, gdy większość operacji wykonywana jest po stronie serwera (jak spawny graczy, ruch zakładników, czy tykanie bomby),
to część wykonywana jest po stronie gracza i serwer nie ma na nie wpływu, jak np. ruch gracza, czy ustalanie odrzutu broni przy strzale.

Informacje nieosiągalne
Poza operacjami, których charakterystyka, dokładny opis, bądź których informacja o wykonaniu, są przesyłane pomiędzy serwerem HLDS, a klientami,
istnieją także operacje, które nie zostają ujawnione dla drugiej strony, zarówno po stronie serwera, jak i u klienta.
Przykładem tych drugich jest np. wywołanie komendy zmiany slotu bądź łączenia się z określonym serwerem.

Warto więc zapamiętać, że nie na wszystkie operacje mamy wpływ, a niektóre czynności gracza mogą nie być dla nas dostępne nawet do odczytania.
Jak już wspomniałem, m.in. informacja o wywołaniu niektórych komend, czyli wpisaniu ich w konsolę, są przesyłane do serwera, a więc możemy je odnotować.

Komendy gracza
Tutaj z pomocą przychodzi nam funkcja register_clcmd, która rejestruje daną komendę u gracza i pozwala na wykonanie danych operacji.
#include <amxmodx>

public plugin_init(){
register_plugin("Komenda klienta", "0.1", "benio101");

register_clcmd("test", "test");
}
W powyższym kodzie widzimy zarejestrowaną komendę test (pierwszy parametr), która zostanie wysłana do AMXX i wywołana zostanie funkcja test (za nazwę funkcji do wywołania odpowiada drugi parametr). Nic nie stoi na przeszkodzie, by nazwa rejestrowanej komendy oraz funkcji, były takie same.

Dodamy zatem funkcję, która zostanie wywołana po wpisaniu przez klienta, polecenia "test" i wyświetlimy na chacie ogólnym temu graczowi, słowo "test".
#include <amxmodx>

public plugin_init(){
register_plugin("Komenda klienta", "0.1", "benio101");

register_clcmd("test", "test");
}

public test(id){
if(is_user_connected(id)){
client_print(id, print_chat, "test");
}
}

W praktyce jednak, najczęściej korzysta się z komendy say, która zbindowana jest u większości graczy pod klawiszami y oraz u.
Chat czy team_chat, to nic innego, jak komenda say z danym parametrem, który podajemy w trakcie gry bez potrzeby otwierania konsoli.

client_print
Funkcja client_print wysyła dla gracza o id podanym w pierwszym parametrze, tekst z trzeciego argumentu w określone miejsce drugim parametrem.
  • print_notify (alternatywnie 1) wyśle wiadomość do konsoli gracza, o ile jest w trybie deweloperskim (rzadko używane)
  • print_console (alternatywnie 2) wyśle wiadomość do konsoli gracza bez względu na to, czy jest w trybie deweloperkim, czy nie
  • print_chat (alternatywnie 3) wyśle wiadomość na chat gracza, widoczny w grze (najczęściej używana opcja)
  • print_center (alternatywnie 4) wyśle wiadomość na samym środku ekranu gracza (trudno ją przegapić)
Używanie nazw print_[notify|console|chat|center] zamiast cyfer jest możliwe, dzięki zastosowaniu struktury typu enum.
Podanie w pierwszym argumencie zera zamiast numeru gracza, wiadomość zostanie wysłana do wszystkich graczy na serwerze.

Chat i TeamChat
Tak więc, zarejestrowanie wydania komendy na chacie jest możliwe, poprzez dodanie prostego "say " lub "say_team " przed
komendą, gdyż docelowo, klient wysyła właśnie komendę poprzedzoną tymi poleceniami do serwera.
Zarejestrujemy teraz przykładową komendę "test" powiedzianą na chacie oraz na team_chacie.
#include <amxmodx>

public plugin_init(){
register_plugin("Komenda klienta", "0.1", "benio101");

register_clcmd("say test", "test");
register_clcmd("say_team test", "test");
}

public test(id){
if(is_user_connected(id)){
client_print(id, print_chat, "Powiedziales test");
}
}
Przejdziemy teraz do bardziej praktycznego zastosowania, czyli do ukrycia na chacie wpisania komendy,
rozpoczynającej się slashem, które zwyczajowo oznaczają specjalną komendę, jak /me czy /hp, wyświetlającą obrażenia.

Ukrycie wpisanych komend
Poza ujrzeniem zadanych, czy otrzymanych obrażeń, nie chcemy, by wszyscy widzieli ten wpis na chacie.
W tym celu zarejestrujemy funkcję say oraz say_team i będziemy blokować wysyłanie komendy do silnika gry,
o ile pierwszym znakiem będzie slash, za pomocą zwrócenia PLUGIN_HANDLED_MAIN. Main, ponieważ nie chcemy
blokować dalszego przepływu informacji innym pluginom, wpisanym niżej w pliku konfiguracyjnym serwera, plugins.ini
#include <amxmodx>

public plugin_init(){
register_plugin("Niewyswietlanie komend ze slashem", "0.1", "benio101");

register_clcmd("say", "say");
register_clcmd("say_team", "say");
}

public say(id){
new txt[192];
read_args(txt,192);
remove_quotes(txt);

if(equali(txt[0],"/")){
return PLUGIN_HANDLED_MAIN;
}

return PLUGIN_CONTINUE;
}


Blokada kupowania broni
Teraz przejdziemy do bardzie praktycznego przykładu, mianowicie
postaramy się zablokować możliwość kupowania broni, granatów i tarczy.

W tym celu będziemy rejestrować daną komendę na kupowanie,
a następnie blokować jej wysyłanie do silnika gry HLDS.

Najpierw jednak, musimy zadać sobie pytanie, w jaki sposób dokonywany jest zakup?
Otóż, standardowo, można korzystać z 2 rodzai menu, bądź poprzez komendę na kupno.
Ostatecznie, komenda w menu, docelowo i tak wysyła do serwera komendę na kupno broni.
Tak więc, pozostaje nam jedynie, wszelkie takie komendy zablokować i kupowanie nie będzie możliwe.

Tutaj odsyłam do podstawowych informacji o broniach: CS Weapons Information
Nazwy komend do blokowania widnieją w kolumnach BUYNAME oraz BUYNAME2.
Druga Kolumna komend na kupowanie, zawiera nazwy ze starszych wersji CSa,
które wciąż są dostępne, by zachować kompatybilność skryptów bindujących.

Nie uwzględnienie tych komend w procesie blokowania, pozwoli nam na kupowanie broni
poprzez wpisanie alternatywnych komend w konsolę, a funkcja, która działa częściowo,
działa źle, gdyż dalej pozostaje możliwość zakupu broni, czego nie chcielibyśmy.

Do spisu komend broni, dodamy kupowanie amunicji (priamammo i secammo), kamizelki (vest i vesthelm),
noktowizora (nvgs), zestawu rozbrajającego (defuser) oraz komend kupowania autobuy i rebuy.
Profilaktycznie, zablokujemy także komendy cl_[set](auto|re)buy oraz komendę buy.

Mając pełen spis komend, wystarczy zarejestrować je wszystkie i następnie zablokować.
Żeby nie tworzyć niepotrzebnie mnóstwa podobnych komend (czyli stosując zasadę DRY),
wpiszemy te wszystkie komendy w tablicę i zarejestrujemy te komendy przy użyciu pętli.
#include <amxmodx>

new static weaponsBuyNames[][]={
"p228", "shield", "scout", "hegren", "xm1014", "mac10", "aug", "sgren", "elites", "fn57",
"ump45", "sg550", "galil", "famas", "usp", "glock", "awp", "mp5", "m249", "m3", "m4a1",
"tmp", "g3sg1", "flash", "deagle", "sg552", "ak47", "p90", "228compact", "autoshotgun",
"bullpup", "fiveseven", "krieg550", "defender", "clarion", "km45", "9x19mm", "magnum",
"smg", "12gauge", "mp", "d3au1", "nighthawk", "krieg552", "cv47", "c90", "primammo",
"secammo", "vest", "vesthelm", "nvgs", "defuser", "autobuy", "rebuy",
"cl_autobuy", "cl_setautobuy", "cl_setrebuy", "cl_rebuy", "buy"
}

public plugin_init(){
register_plugin("Blokada kupowania", "0.1", "benio101");

for(new i=0; i<sizeof weaponsBuyNames; ++i){
register_clcmd(weaponsBuyNames[i], "block");
}
}

public block(){
return PLUGIN_HANDLED_MAIN;
}

Użytkownik benio101 edytował ten post 09.12.2012 03:07
+kot.


#2 K!113r

    Teraz to chyba Sławek kek

  • Power User

Reputacja: 387
Wszechpomocny

  • Postów:868
  • GG:
  • Steam:steam
  • Imię:Mateusz
  • Lokalizacja:Piotrków Tryb.
Offline

Napisano 03.12.2012 20:19

Po tytule myślałem że to będzie coś innego... (wyświetlanie wiadomości graczowi :D ), ale znów dowiedziałem się tylu ciekawych informacji ^^
Oby więcej takich poradników.

#include <amxmodx>

public plugin_init(){
register_plugin("Komenda klienta", "0.1", "benio101");

register_clcmd("test", "test");
}

public test(id){
if(is_user_connected(id)){
client_print(id, "test");
}
}


Popraw tylko ten client_print, więcej błędów się nie dopatrzyłem.
(03.12.2012 20:26):
Poprawione ;>

Użytkownik benio101 edytował ten post 03.12.2012 20:26
Dodanie znacznika SMA

  • +
  • -
  • 0

DarkGL to mój autorytet.

skomplikować skomplikować skomplikować skomplikować skomplikować skomplikować skomplikować skomplikować skomplikować skomplikować skomplikować skomplikować skomplikować skomplikować


#3 speedkill

    Godlike

  • Przyjaciel

Reputacja: 1 592
Godlike

  • Postów:2 733
  • GG:
  • Steam:steam
  • Imię:Michał
  • Lokalizacja:Prudnik
Offline

Napisano 03.12.2012 20:32

Fajnie, możesz opisać także wyświetlanie tekstu, jego typ ( w sensie, gdzie ma się on wyświetlić można zamienić cyfrą np. 3 -> print_chat ). Przy rejestrowaniu komend clcmd nie trzeba sprawdzać, czy gracz jest połączony z serwerem ;)
(03.12.2012 20:48):
Dopisane

  • +
  • -
  • 0

If you can dream it, you can do it.


#4 GwynBleidD

    Godlike

  • Przyjaciel

Reputacja: 1 869
Godlike

  • Postów:3 066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 08.12.2012 09:57

Masz byka przy warunkach logeventów. Przy mniejszości masz podane:
arg>val

(08.12.2012 10:28):
Dzięki, poprawione.

  • +
  • -
  • 0

NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark


#5 wheypro

    Pomocny

  • Zbanowany

Reputacja: -25
Masakra

  • Postów:74
  • Lokalizacja:Zakaz podawania adresów stron w polu "Lokalizacja" itp.
Offline

Napisano 30.01.2013 10:06

Zauważyłem że zarówno dokumentacja amxx i te tuturiale są napisane językiem matematyków/logików/programistów. Niewiele osób czytając to a nie mając uprzednio funktorów prawdziwościowych w ogóle nie zrozumie oco biega:

-koniunGcja(nie koniunkcja) tzn, że wszelkie argumenty muszą być spełnione by coś wywołać:
np.
Art 209 KK:
§ 1. Kto uporczywie uchyla się od wykonania ciążącego na nim z mocy ustawy lub orzeczenia sądowego obowiązku opieki przez niełożenie na utrzymanie osoby najbliższej lub innej osoby i przez to naraża ją na niemożność zaspokojenia podstawowych potrzeb życiowych, podlega grzywnie, karze ograniczenia wolności albo pozbawienia wolności do lat 2.

Muszą być spełnione 2 wymogi by sprawca odpowiadał z tego czynu zabronionego(fachowo mówi się "wyczerpał znamiona ustawowe dyspozycji art .."):
Tak więc jeśli np tylko uchyla się od tego ale nie naraża tym na "niemożność zaspokojenia podstawowych potrzeb życiowych" to nie odpowiada z tego artykułu. Tak samo jest tutaj: " o ile koniungcja warunków z argumentów opcjonalnych zostanie spełniona." Jeśli więc jeden z nich nie jest spełniony to nic się nie wywoła.

Alternatywa zwykła:
Oznacza że w naszym przypadku funkcja się wywoła jeśli oba warunki bedą spełnione albo jeden z nich:
ART 207KK
1. Kto znęca się fizycznie lub psychicznie nad osobą najbliższą lub nad inną osobą pozostającą w stałym lub przemijającym stosunku zależności od sprawcy albo nad małoletnim lub osobą nieporadną ze względu na jej stan psychiczny lub fizyczny, podlega karze pozbawienia wolności od 3 miesięcy do lat 5.

Tzn. że sprawca odpowie z tego artykuły jesli jego zachowanie było znęcanieim się psychicznym lub fizycznym zarówno na
"osobie najbliższej" jak i "pozostającą w stałym lub przemijającym stosunku zależności". Wystraczy więc by na tylko jedenj z nich się znęcał a już podegla ów karze.

Alternatywa rozłączona: Tylko jeden z warunków musi być spełniony, nie mogą być 2:

§ 1. Kto zabija człowieka, podlega karze pozbawienia wolności na czas nie krótszy od lat 8, karze 25 lat pozbawienia wolności albo karze dożywotniego pozbawienia wolności.

Zabójca idzie do jaila na nie mniej niż 8 lat, 25 lat albo resztę swego życia. Nie może iśc na 25 lat i dożywocie.

Jeśli tak macie pisać te tuturiale, bazując na logice i jakiemś nazewnictwu informtycznym to se darucjcie bo nikt z tego nic nie zrozumie.

#6 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 30.01.2013 10:59

-koniunGcja(nie koniunkcja)

Nie wiem skąd masz taką wiedzę, ale niestety źle myślisz, pisze się koniunKcja, a co do tego, że są używane takie wyrażenia, to jak ktoś rzeczywiście chce się czegoś nauczyć, to sobie taki wyraz "wygogluje" i będzie wiedział ocb.
  • +
  • -
  • 1

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo





Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych