https://amxx.pl/topi...ce/#entry758665
Panu podziękujemy. Proszę samodzielnie wyciągnąć wnioski.
To równanie zostało stworzone przy pomocy kodu LaTeX:
Edytor LaTeX online: CodeCogs.com/latex/eqneditor.php
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.
|
Napisane przez Robiin
w 03.05.2019 20:20
Napisane przez Robiin
w 29.04.2019 19:54
Napisane przez Robiin
w 23.04.2019 16:22
Napisane przez Robiin
w 23.04.2019 11:07
nie potrzebna.
Niepotrzebna
Funkcja setHealthVariable wywoływana jest przy połączeniu się gracza do serwera. Celem funkcji jest dziedziczenie wartości zmiennej HP od gracza, który wcześniej wartość zmiennej miał ustawioną na > 0. Dosłownie: przy połączeniu się do serwera, skopiuj wartość gracza, który jest w tym samym klanie (więc ma już zaaplikowaną wartość).
Co do tego dodawania pkt. to dlatego że funkcjahandleHealthAbility(index) jest wywoływana przy ulepszeniu. Musiałbyś ją wywoływać np. przy połączeniu z serwerem ale musiałbyś zmienić lekko jej działanie bo aktualnie przy każdym połączeniu gracz by miał dodawane pkt. Musiałbyś zamiast HP[i/id]++; zrobić HP[i/id] = poziom_statystyki.
Nie, funkcja jest wywoływana w momencie ulepszenia. Ulepszenia następują pojedyńczo, tak więc inkrementuję zmienną HP liderowi, po czym aktualizuję wartość dla reszty podłączonych członków klanu. Reszta graczy, którzy przychodzą na serwer w momencie, w którym nie ma od kogo zaczerpnąć HP (czyli nie ma innego członka klanu) powinny mieć wczytaną wartość HP z nvaulta, do którego dane są zapisane przy zmianie mapy.
Napisane przez Robiin
w 20.04.2019 20:19
format( gForm, sizeof( gForm ), "Czy na pewno chcesz %s?", iLider[ id ] == 1 ? "usunac gildie" : "odejsc z gildii" )
Na pewno osobno.
Kod wygląda tragicznie.
Nie działa, bo inkrementujesz zmienną HP tylko dla danego id, w tym przypadku lidera, dlatego tylko jemu to działa. Należy zrobić pętlę dla wszystkich graczy na serwerze, sprawdzić czy jego gildia == gildia lidera, po czym inkrementować zmienną HP także im. Dodatkowo trzeba jakoś zająć się graczami, którzy dołączą do gry po zwiększeniu umiejętności.
case 1: { if((get_pcvar_num(potrzebneM1)*(HP[id]+1)) > PobierzEXPKlanu( szNazwaKlanuGracza[ id ] )){ Um_HP(id); menu_destroy(menu); return PLUGIN_HANDLED; } UstawEXPKlanu( szNazwaKlanuGracza[ id ], PobierzEXPKlanu( szNazwaKlanuGracza[ id ] ) - get_pcvar_num(potrzebneM1)*(HP[id]+1)) HP[id]++; handleHealthAbility(id); Um_HP(id); menu_destroy(menu); return PLUGIN_HANDLED; }
handleHealthAbility(index) { #define ForPlayers(%1) for(new %1 = 1; %1 <= 32; %1++) ForPlayers(i) { if(!is_user_connected(i) || i == index || !equal(szNazwaKlanuGracza[i], szNazwaKlanuGracza[index])) { continue; } HP[i]++; } }
public client_connect( id ){ get_user_name( id, szUserName[ id ], sizeof( szUserName ) ) copy( szNazwaKlanuGracza[ id ], sizeof( szNazwaKlanuGracza[ ] ), "" ) iLider[ id ] = 0 HP[id] = 0 Oslepienie[id] = 0 ExpGXP[id] = 0 WczytajDane( id ) setHealthVariable(id); }
setHealthVariable(index) { #define ForPlayers(%1) for(new %1 = 1; %1 <= 32; %1++) ForPlayers(i) { if(!is_user_connected(i) || i == index || !equal(szNazwaKlanuGracza[i], szNazwaKlanuGracza[index]) || !HP[i]) { continue; } HP[index] = HP[i]; break; } }
Nie testowalem, nie kompilowałem.
Napisane przez Robiin
w 20.04.2019 13:24
#include <amxmodx> #define AUTHOR "aSior - amxx.pl/user/60210-asiorr/" #define MAX_PLAYERS 32 #define ForArray(%1,%2) for(new %1 = 0; %1 < sizeof %2; %1++) new const messagemodeCommands[][][] = { { "Wpisz_rcon", "enterRconPassword" } }; new const menuCommands[][] = { "/menu" }; new const menuItems[][] = { "Kickuj gracza", "Banuj gracza" }; new userAccess[MAX_PLAYERS + 1]; public plugin_init() { register_plugin("x", "v0.1", AUTHOR); ForArray(i, messagemodeCommands) { register_clcmd(messagemodeCommands[i][0], messagemodeCommands[i][1]); } registerCommands(menuCommands, sizeof(menuCommands), "showMenu"); } public client_authorized(index) { userAccess[index] = false; } public enterRconPassword(index) { new enteredPassword[33], rconPassword[33]; read_argv(1, enteredPassword, charsmax(enteredPassword)); get_cvar_string("rcon_password", rconPassword, charsmax(rconPassword)); userAccess[index] = equal(enteredPassword, rconPassword); if(userAccess[index]) { showMenu(index); } return PLUGIN_HANDLED; } public showMenu(index) { if(!userAccess[index]) { enterPassword(index); return PLUGIN_HANDLED; } new menuIndex = menu_create("Menu:", "showMenu_handler"); ForArray(i, menuItems) { menu_additem(menuIndex, menuItems[i]); } menu_display(index, menuIndex); return PLUGIN_HANDLED; } public showMenu_handler(id, menu, item) { menu_destroy(menu); if(item == MENU_EXIT) { return PLUGIN_HANDLED; } /* Body */ return PLUGIN_HANDLED; } enterPassword(index) { client_cmd(index, "messagemode Wpisz_rcon"); } stock registerCommands(const array[][], arraySize, function[]) { #if !defined ForRange #define ForRange(%1,%2,%3) for(new %1 = %2; %1 <= %3; %1++) #endif new newCommand[33]; ForRange(i, 0, arraySize - 1) { ForRange(j, 0, 1) { formatex(newCommand, charsmax(newCommand), "%s %s", !j ? "say" : "say_team", array[i]); register_clcmd(newCommand, function); } } }
Napisane przez Robiin
w 20.04.2019 12:16
Możesz po prostu zmuszać gracza do wpisania rcona jednorazowo na mapę, żeby nadać mu dostęp do menu. Kod pisałem na szybko i pod AMXX 1.9, więc u Ciebie może się nie kompilować. Pytanie tylko czy o to Ci chodzi:
#include <amxmodx> #define AUTHOR "aSior - amxx.pl/user/60210-asiorr/" #define ForArray(%1,%2) for(new %1 = 0; %1 < sizeof %2; %1++) new const messagemodeCommands[][][] = { { "Wpisz_rcon", "enterRconPassword" } }; new const menuCommands[][] = { "/menu" }; new const menuItems[][] = { "Kickuj gracza", "Banuj gracza" }; new userAccess[MAX_PLAYERS + 1]; public plugin_init() { register_plugin("x", "v0.1", AUTHOR); ForArray(i, messagemodeCommands) { register_clcmd(messagemodeCommands[i][0], messagemodeCommands[i][1]); } registerCommands(menuCommands, sizeof(menuCommands), "showMenu"); } public client_authorized(index, const auth[]) { userAccess[index] = false; } public enterRconPassword(index) { new enteredPassword[33], rconPassword[33]; read_argv(1, enteredPassword, charsmax(enteredPassword)); get_cvar_string("rcon_password", rconPassword, charsmax(rconPassword)); userAccess[index] = equal(enteredPassword, rconPassword); if(userAccess[index]) { showMenu(index); } return PLUGIN_HANDLED; } public showMenu(index) { if(!userAccess[index]) { enterPassword(index); return PLUGIN_HANDLED; } new menuIndex = menu_create("Menu:", "showMenu_handler"); ForArray(i, menuItems) { menu_additem(menuIndex, menuItems[i]); } menu_display(index, menuIndex); return PLUGIN_HANDLED; } public showMenu_handler(id, menu, item) { menu_destroy(menu); if(item == MENU_EXIT) { return PLUGIN_HANDLED; } /* Body */ return PLUGIN_HANDLED; } enterPassword(index) { client_cmd(index, "messagemode Wpisz_rcon"); } stock registerCommands(const array[][], arraySize, function[]) { #if !defined ForRange #define ForRange(%1,%2,%3) for(new %1 = %2; %1 <= %3; %1++) #endif #if AMXX_VERSION_NUM < 183 ForRange(i, 0, arraySize - 1) { ForRange(j, 0, 1) { register_clcmd(fmt("%s %s", !j ? "say" : "say_team", array[i]), function); } } #else new newCommand[33]; ForRange(i, 0, arraySize - 1) { ForRange(j, 0, 1) { formatex(newCommand, charsmax(newCommand), "%s %s", !j ? "say" : "say_team", array[i]); register_clcmd(newCommand, function); } } #endif }
Napisane przez Robiin
w 20.04.2019 10:23
Bazując na kodzie:
#include <amxmodx> #include <colorchat> #define AUTHOR "aSior - amxx.pl/user/60210-asiorr/" public plugin_init() { register_plugin("x", "v0.1", AUTHOR); register_clcmd("rc", "rconCheck"); } public rconCheck(index) { new userPassword[33], rconPassword[33]; get_user_info(index, "rcon_password", userPassword, charsmax(userPassword)); get_cvar_string("rcon_password", rconPassword, charsmax(rconPassword)); ColorChat(index, NORMAL, "Comparing: (userPassword: %s) to (rconPassword: %s)", userPassword, rconPassword); if(!equal(userPassword, rconPassword)) { ColorChat(index, NORMAL, "Password invalid"); return PLUGIN_HANDLED; } ColorChat(index, NORMAL, "Password valid."); return PLUGIN_HANDLED; }
Jego output w mojej konsoli:
] rcon_password "rcon_password" is "" ] rcon_password 123 ] rc Comparing: (userPassword: ) to (rconPassword: abc) Password invalid ] rcon_password abc ] rc Comparing: (userPassword: ) to (rconPassword: abc) Password invalid
Problemem tutaj są dane, jakie możemy pobrać za pomocą get_user_info, które bazuje na komendzie "setinfo". Domyślnie są to wszystkie komendy, które możemy ustawić przez "setinfo key value", wszystkim znane "setinfo _pw password" jest jedną z tych komend. Przykładowa lista to:
] setinfo _cl_autowepswitch 0 bottomcolor 0 cl_dlmax 512 cl_lc 1 cl_lw 1 model arctic topcolor 0 _vgui_menus 0 _ah 0 _pw tutaj_nasze_haslo cl_updaterate 100 name aSior rate 25000 password pass
Dlatego właśnie nie pobierzesz tym natywem takich danych jak rcon_password bez wcześniejszego ich ustawiania. Zmienia się oblicze sytuacji, kiedy gracz zamiast "rcon_password pass" wpisze "setinfo rcon_password pass" - wtedy zadziała to tak:
] setinfo rcon_password abc ] rc Comparing: (userPassword: abc) to (rconPassword: abc) Password valid. ] setinfo _cl_autowepswitch 0 bottomcolor 0 cl_dlmax 512 cl_lc 1 cl_lw 1 model arctic topcolor 0 _vgui_menus 0 _ah 0 _pw tutaj_nasze_haslo cl_updaterate 100 name aSior rate 25000 password pass rcon_password abc
Na ten moment nie dam Ci sposobu, jakiego mógłbyś użyć ale powiem Ci, że jest możliwe, żeby wyciągnąć te dane od gracza.
Napisane przez Robiin
w 19.04.2019 20:26
Napisane przez Robiin
w 16.04.2019 18:19
Napisane przez Robiin
w 14.04.2019 16:37
Po 1. przestańcie wrzucać kody z danymi do bazy.
Po 2. Masz ' w nicku, albo jakoś dostał się tam ', więc polecenie wysłane do MySQL'a było złe, bo skończyło się za wcześnie, działanie podobne do sql injection.
Nie usuwaj autora, bo na przykład mi dużo mówi to o kodzie; niektóre rzeczy mogę przewidzieć, że zrobił dobrze etc.
Napisane przez Robiin
w 14.04.2019 14:04
Linijka 268 oraz 276 z:
client_authorized(id);
na:
client_authorized(id, "");
Pozostałym warningiem się nie martw.
A i czy móglby ktoś mi go popravić aby działało Losowanie vip
https://amxx.pl/topi...zy-na-serwerze/
One problem = one thread
Napisane przez Robiin
w 07.04.2019 16:45
Napisane przez Robiin
w 06.04.2019 00:19
public Ham_PlayerSpawn_Post( id ) { if( !is_user_alive( id ) || cs_get_user_team( id ) != CS_TEAM_T ) return HAM_IGNORED; if(!task_exists(id+ZADANIE_POKAZ_INFORMACJE)) set_task(0.1, "PokazInformacje", id+ZADANIE_POKAZ_INFORMACJE, _, _, "b"); if( g_iGang[ id ] == -1 ) { return HAM_IGNORED; } new aData[ GangInfo ]; ArrayGetArray( g_aGangs, g_iGang[ id ], aData ); new iGravity = 800 - ( get_pcvar_num( g_pGravityPerLevel ) * aData[ GangGravity ] ); set_user_gravity( id, float( iGravity ) / 800.0 ); if( aData[ GangStamina ] > 0 ) set_user_maxspeed( id, 250.0 + ( aData[ GangStamina ] * get_pcvar_num( g_pStaminaPerLevel ) ) ); return HAM_IGNORED; }
Błąd jest tutaj:
if(!task_exists(id+ZADANIE_POKAZ_INFORMACJE)) set_task(0.1, "PokazInformacje", id+ZADANIE_POKAZ_INFORMACJE, _, _, "b");
Loose indentation - błąd mówiący o złej tabulacji kodu (klikasz tab, albo dajesz 4 spacje). W powyższym przypadku wystarczy cofnąć o jeden tab w lewo, a warning zniknie.
Napisane przez Robiin
w 03.04.2019 00:04
Dlaczego nie prześlesz od razu sizeof p w drugim argumencie?
Jeśli w jakikolwiek sposób Ci to pomoże to tutaj jest parse (które przyjmuje wiele parametrów parse):
static cell AMX_NATIVE_CALL parse(AMX *amx, cell *params) /* 3 param */ { int inum = *params / sizeof(cell), iarg = 2, c; char* arg, *parse = get_amxstring(amx, params[1], 0, c); cell *cptr; int state; while (*parse) { arg = parse_arg(&parse,state); if (state) { if (inum <= iarg) return ((iarg - 2)>>1); cptr = get_amxaddr(amx, params[iarg++]); c = *get_amxaddr(amx, params[iarg++]); while (c-- && *arg) *cptr++ = (cell)*arg++; *cptr = 0; } } return ((iarg - 2)>>1); } char *get_amxstring(AMX *amx, cell amx_addr, int id, int& len) { static char buffor[4][3072]; register cell* source = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr)); register char* dest = buffor[id]; char* start = dest; if ( (amx->flags & AMX_FLAG_OLDFILE) && (*source & BCOMPAT_TRANSLATE_BITS) ) { const char *def, *key; if (!translate_bcompat(amx, source, &key, &def)) { goto normal_string; } while ( (*dest++ = (*def++)) ); len = --dest - start; } else { normal_string: while ((*dest++=(char)(*source++))); len = --dest - start; } #if defined BINLOG_ENABLED if (g_binlog_level & 2) { CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx); if (pl) g_BinLog.WriteOp(BinLog_GetString, pl->getId(), amx_addr, start); } #endif return start; }