Szerző Téma: Bemutatkozás rendszer  (Megtekintve 2201 alkalommal)

Nem elérhető myke

  • 213
    • Profil megtekintése
Bemutatkozás rendszer
« Dátum: 2016. január 08. - 21:55:15 »
0 Show voters
Sziasztok!
Jó rég, már valaki kérdezte ezt a fórumon, de nem kapott választ rá. Elkezdtem írni egy módot SQL-ben, és szeretnék írni egy ilyen bemutatkozós rendszert hozzá. Hogy tudnám megoldani? Én arra gondoltam, hogy csinálok egy külön bemutatkozasok táblát, és valahogy úgy oldanám meg. De innentől elfogyott az én kreatívitásom/logikám, ezért kérném a ti segítségeteket, hogy hogyan lehetne ezt megvalósítani a gyakorlatban is.
Illetve, lenne egy ehez kapcsolódó kérdésem. Van egy /me parancsom, ahol a cselekvés előtt azt írja, hogy \"Valaki\". Hogyan tudnám megoldani, hogy csak nekem azt írja, hogy \"Én\", és a többi embernek azt, hogy \"Valaki\"? Előre is köszönöm a segítségkeket és a válaszokat mind a két kérdésemre.

Nem elérhető KovaNovik

  • 1121
  • KovaNovik
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #1 Dátum: 2016. január 10. - 00:30:36 »
+5 Show voters
Láttam én már a kérdésed, mikor kiírtad, csak lusta voltam leírni az igazat megvallva :D
Én a következőképpen oldanám meg:
I, Létrehozok egy bemutatkozasok táblát a következő oszlopokkal:
id(LONG_INT, A_I), ki(varchar 24), kinek(varchar 24)
II, A \"/bemutatkoz\" parancs kiadásánál a következő kód fut le:
1. Nyilvánvalóan, sscanf()-fel feldarabolom a parancs paramétereit, illetve az \"r\" paramétert használom (ez játékos nevet vagy id-t érzékel, botot nem), eltárolom az id-t mondjuk egy playerid2 változóba.
2. Leellenőrzöm, hogy nem-e bemutatkozott-e már; ezt egy select queryvel: kiválasztom a bemutatkozasok táblát, ahol ki=`%s`, oda pedig format-tal beilleszted playerid nevét, hiszen azt a sort akarjuk kijelölni, ahol ő mutatkozott be, illetve kinek=`%s`, ide pedig nyilván playerid2 neve kerül. A cache_get_row_count() a talált sorok számával tér vissza (a mysql_tquery()-nél megadott function-ben!!).
3. Amennyiben a fenti érték 1 - azaz már bemutatkozott -, hibaüzenettel térek vissza, ha viszont 0 - tehát még nem mutatkozott be playerid playerid2-nek, beillesztek egy sort a nevükkel, és kiírom mindkettejüknek, hogy mi történt, esetleg még playerid2-nek azt, hogy ő ugyanígy, a \"/bemutatkoz\" paranccsal mutatkozhat be a másik játékosnak.
4. Minden parancsnál, ahol a többi játékos felé kell kiírnom valaki nevét, leellenőrzöm, hogy bemutatkozott-e már neki az illető. Egy select queryvel kiválasztom azokat az oszlopokat, ahol a ki=playerid-neve. Így le tudom kérni egy ciklussal egy tömbbe mindazon játékosok listáját, akiknek már bemutatkozott playerid (a /me írója). Így, a SendClientMessageToAll() helyett egy ciklust használva, kiszűrve azt aki nem online, nincs belépve, vagy nincs a közelben, csak a fenti feltételeknek megfelelő játékosoknak kiírom: HA már bemutatkozott (végigment a query és volt az egyik névvel egyezés, ezt egy ideiglenes változóban tárolhatod pl.), akkor a nevét írom ki a cselekvése elé, HA VISZONT NEM (azaz az ideiglenes változó nem változott 1-re, mikor \"azon játékosok listájá\"-t nézte át a fő cikluson belüli ciklus, akik már bemutatkoztak playerid-nek), azaz nem volt egyezés egyik névvel sem, csupán annyit írok ki, hogy valaki, majd a cselekvés.
III, Hogyan működik ez a gyakorlatban?
Adott két játékos: Eric_Cartman(0), Stan_Marsh(1).
Eric beírja: /bemutatkoz Stan_M
Stan_M-et érzékeli mint 1-es id-t az sscanf, aki online van, belépve, és Eric közelében is (IsPlayerInRangeOfPoint). A bemutatkozasok táblába beírásra kerül:
id=`0` ki=`Eric_Cartman` kinek=`Stan_Marsh`
Ezentúl amikor Eric /me-t ír, a /me parancsnál a táblában megtalálja a rendszer, hogy mely sor(ok)ban igaz az, hogy ki=Eric_Cartman. Ez esetünkben a következő sor: id=`0` ki=`Eric_Cartman` kinek=`Stan_Marsh`. Ekkor \"azon játékosok listája, akiknek már bemutatkozott Eric Cartman\" a következő, egy stringgel rendelkező tömb lesz: {{\"Stan_Marsh\"}}. Így mikor a /me ciklus a 0-s id-nél jár, látja, hogy online, belépve, és a közelben van a játékos, majdpedig látja, hogy i=playerid, ezért Én-t ír ki valaki helyett. Továbbmegy a ciklus a következő iterációra, immáron i=1; itt végigpörget a tömb elemein, és mivel csak 1 eleme van (egyelőre, mivel csak 1 ember volt, aki bemutatkozott Ericnek), hamar végigfut. Látja, hogy Stan_Marsh neve egyezik i nevével (1-es id-jű játékos), ezért átállítja t ideiglenes változót 1-re. Mivel t=1, kiírja neki Eric nevét. Ha lenne valaki más, ahol t=0 maradna (if (t==0)), mivel nem mutatkozott volna még be neki Eric, akkor neki csak Valakit írna ki Eric helyett.
Ugyanezt be tudod illeszteni az OnPlayerText-hez is, meg a /do parancshoz is, meg ahova akarod. Bele lehet még keverni egy maszk rendszert, mindent.
Figyelem! Lehet, hogy célszerűbb lenne nem minden egyes alkalommal SQL-lekéréseket indítani, mikor valakinek a neve szóba esik. Lehet, hogy jobb lenne emberek ismerőseinek a listáját tömbökben tárolni, azokat módosítgatni-szerkesztgetni, és csak bizonyos időközönként, illetve szerver-leállításkor elmenteni a dolgokat. Az előbbi, fent kifejtett megoldás valós idejű, ennyi az előnye, ha crashel a szerver, nem veszik el adat, mert mondjuk csak fél perc múlva jött volna az automatikus mentés, addig meg 20 ember bemutatkozott egymásnak. Az is lehet, hogy jobb lenne egy AreFriends(playerid1, playerid2) funkciót írni és unthreaded queryvel és cache-el megoldani a dolgot, hogy egyszerűsítsünk a kódon, bár ezt nem javasolják, mert laggot okozhat az unthreaded query jellege miatt (egyszerre nem tud több futni).
Meg szeretnélek kérni arra, hogy ha van valami kérdésed ezzel kapcsolatban, ne PM-et írj, inkább itt beszéljük/vitassuk/oldjuk meg, ezzel is javára válva a közösségnek. Ha már küldesz egy félkész kódot, hogy segítsünk kijavítani, az is több, mint a semmi, próbálkozni szabad, szívesen segítünk.
Köszönöm előre is.

Nem elérhető myke

  • 213
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #2 Dátum: 2016. január 10. - 13:39:21 »
0 Show voters
Nos, hát rengeteget segítettél, viszont szükségem lenne még egy kicsire. :D
Nos, próbálkoztam, és összehoztam valamit, de nem nagyon működik.
 
funkcio Bemutatkozas1( playerid, playerid2 )
{
new sorok_szama = cache_get_row_count();
if(sorok_szama == 0)
{
    new query1[256];
mysql_format(kapcs, query1, 256,\"INSERT INTO \'bemutatkozasok\' (`ki`,\'kinek\') VALUES (\'%s\', \'%s\')\",Neve(playerid),Neve(playerid2));
mysql_tquery(kapcs, query1, \" \", \"\");
cmd_me(playerid, \"bemutatkozik valakinek\");
SFM(playerid2, FONTOS, \"(( %s bemutatkozott neked. ))\", Neve(playerid));
SCM(playerid, ZOLD, \"(( Bemutatkoztál az illetőnek. ))\");
}else HIBA(playerid, \"(( Te már bevagy mutatkozva neki. ))\");
return 1;
}
CMD:bemutatkozas(playerid,params[])
{
new playerid2;
if(sscanf(params, \"u\", playerid2)) return SendClientMessage(playerid, ZOLD, \"Használat: /bemutatkozas < Név / Id >\");
     if(!IsPlayerConnected(id)) return SendClientMessage(playerid, ZOLD, \"A játékos nem elérhető!\");
new Float:vX, Float:vY, Float:vZ;
    GetPlayerPos(playerid2, vX, vY, vZ);
if(!IsPlayerInRangeOfPoint(playerid, 3.0, vX, vY, vZ)) return SendClientMessage(playerid, PIROS, \"Nincs a közeledben senki!\");
new query2[256];
mysql_format(kapcs, query2, 256, \"SELECT * FROM \'bemutatkozasok\' WHERE ki=`%s` AND kinek=`%s`\", Neve(playerid), Neve(playerid2));
mysql_tquery(kapcs, query2, \"Bemutatkozas1\", \"dd\", playerid, playerid2);
return 1;
}

 
Valamiért nem csinál semmit a parancsra. Mi lehet a baj? Esetleg Ti, hogy oldanátok meg?

Nem elérhető KovaNovik

  • 1121
  • KovaNovik
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #3 Dátum: 2016. január 10. - 14:55:44 »
+1 Show voters
Működési (logikai) sorrendben nézem végig a kódot.


1. 25. sor:
 
return SendClientMessage(playerid, PIROS, \"Nincs a közeledben senki!\");

 
Nincs a közeledben a kiválasztott játékos, inkább. De ezen nem múlik sokminden. :D
2.
Neve(playerid)

 
Ez alsóvonással, vagy anélkül tér vissza a nevével? Lehetőleg úgy kellene, ahogy a bemutatkozasok táblában tárolva van. Bár szinte biztos vagyok benne, hogy ez sem okozza EZT a hibát, de szerintem jobb lenne egy Nev[MAX_PLAYERS][24] tömbben tárolni a neveket bejelentkezéskor, így csak onnan kéne olvasnia, nem kell minden egyes lekérésnél végigfutnia egy plusz függvénynek, stb.
3.
SELECT * FROM \'bemutatkozasok\' WHERE ki=`%s` AND kinek=`%s`

 
Ilyen ` jelet magyar billentyűn Alt Gr + 7-tel tudsz írni. Én mindig aposztrófot használtam (\') (a tutorialomban is), de most profinak akartam tűnni és úgy írni, ahogy azt a legtöbb más helyen is szokták. Lehetőleg mindegyik legyen egyforma, bár sosem próbáltam még ki, hogy ez okoz-e valamiféle gubancot.
Ha ennek még a formázásnál használt hosszába is bele akarnék kötni, azt mondanám, hogy legyen a maximális mérete + 1.
A következőképp számolok:
beillesztem ide >ERRE AZ OLDALRA< a következő queryt (%s-ek nélkül nyilván):
 
SELECT * FROM `bemutatkozasok` WHERE ki=`` AND kinek=``

 
Erre kiadja, hogy 55 karakter hosszú. Még ehhez hozzájön 24+24 karakter (mindkét player nevének maximális hossza), ami 103, plusz egy kell a string lezárásához (nekérdezd ;)). 104-re elég formázni (és a tömb méretének is elég ennyi). A %s-ek attól kellenek a formatba, csak a hossz méréséhez vettük ki ideiglenesen!!
Illetve MySQL format-ot csak akkor használnék szívem szerint (bár nem tudom miben különbözik a sima formattól), ha escape karaktert írok bele (%e), melyet csak ez a funkció tud.
Annyira nagy hiba itt sem volt, csak megnyugtatta a spúr lelkemet, ez a felszabadult 152 byte (256>>104).
4.
A 6-7. sorban a következő query méretét megint csak módosítanám (az aposztrófok kijavítása mellett):
 
INSERT INTO \'bemutatkozasok\' (`ki`,\'kinek\') VALUES (\'%s\', \'%s\')

 
Ez a fenti oldal segítségével végzett számításaim szerint (kicsit megszépítve %s-ek nélkül):
 
INSERT INTO `bemutatkozasok` (`ki`,`kinek`) VALUES (``,``)

 
58+24+24+1=141 karakter hosszú, szóval annyira pont elég formázni, és a tömb méretének is elég.
 

A 3. és 4. pontot próbáld meg 24 karakter hosszú nevekkel a biztonság kedvéért! Ha lehagy egy karaktert, próbáld újra úgy, hogy a tömb méretét eggyel kisebbre, a formatot pedig eggyel kisebb méretűre veszed. Nem emlékszem már pontosan erre!

Ezen kívül nem tudok mit mondani. Be van kapcsolva a mysql_logolás? Nézd meg ott, hátha segít.

Nem elérhető myke

  • 213
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #4 Dátum: 2016. január 10. - 15:30:30 »
0 Show voters
Aposztrófok cserélve. A Neve(playerid) függvény alsóvonallal tér vissza. Kijavítottam azokat a dolgokat amiket írtál, de sajnos így se jó. A mysql_log a következőt írja:
 
[15:13:51] [ERROR] CMySQLQuery::Execute[bemutatkozas1] - (error #1054) Unknown column \'Kiss_Pista\' in \'where clause\'

 
Ezt miért írhatja?
Illetve, gondolkodtam, és mi lenne, ha nem név alapján menteném a bemutatkozást, hanem adatbázis ID alapján? Úgy nem egyszerűbb?

Nem elérhető KovaNovik

  • 1121
  • KovaNovik
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #5 Dátum: 2016. január 10. - 16:46:40 »
0 Show voters
Ha ID alapján csinálod, azt is név alapján kéred le, tehét lényegében csak plusz egy lekérést csinálsz.
Az SQL log pedig azt írja, hogy nem talál Kiss_Pista nevű oszlopot.
Keresel egyátalán valahol olyat? :O
A Bemutatkozas1 funkcióra írja, de ott nincsen olyan.
« Utoljára szerkesztve: 2016. január 10. - 16:50:17 írta kovanovik »

Nem elérhető myke

  • 213
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #6 Dátum: 2016. január 10. - 16:51:18 »
0 Show voters
Hát, őszintén megmondom, nem tudom.  :D
 
   Format(query2, \"SELECT * FROM `bemutatkozasok` WHERE ki=`%s` AND kinek=`%s` LIMIT 1\", Neve(playerid), Neve(playerid2));
mysql_tquery(kapcs, query2, \"Bemutatkozas1\", \"dd\", playerid, playerid2);

 
Nem erre írja? Vagy a \"Bemutatkozas1\" függvénybe szúrtam el valamit?

Nem elérhető KovaNovik

  • 1121
  • KovaNovik
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #7 Dátum: 2016. január 10. - 17:13:26 »
0 Show voters
A format() kisbetű, kell bele hosszúság (sizeof(query2)). Mivel odaírtad, hogy \" LIMIT 1\" (ami nem hülyeség, javasolni is akartam!), ezért nyilván 8 karakterrel hosszabb lesz a query.
Ezt rakd még be az OnGameModeInit elejére:
 
mysql_log(LOG_ALL, LOG_TYPE_HTML);

 
Ezzel így elméletileg egy mysql_log.html fájlba mindent kiír majd, ami csak történik. Ha hiba van, így láthatjuk az azt megelőző történéseket is, így könnyebb lesz azt körülhatárolni.
« Utoljára szerkesztve: 2016. január 10. - 17:15:04 írta kovanovik »

Nem elérhető myke

  • 213
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #8 Dátum: 2016. január 10. - 17:50:16 »
0 Show voters
Tudom, hogy a format kisbetű, csak picit levan egyszerűsítve úgy, hogy nekelljen sizeofot odaírni. :D
Itt az mysql html log.
\"64415749.jpg\"

Nem elérhető Pedró

  • 3341
  • 2014 © Az év Szkriptere
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #9 Dátum: 2016. január 10. - 17:51:29 »
0 Show voters
Format(query2, \"SELECT * FROM `bemutatkozasok` WHERE ki=`%s` AND kinek=`%s` LIMIT 1\", Neve(playerid), Neve(playerid2));

 
helyett
 
Format(query2, \"SELECT * FROM `bemutatkozasok` WHERE ki=\'%s\' AND kinek=\'%s\' LIMIT 1\", Neve(playerid), Neve(playerid2));

Nem elérhető KovaNovik

  • 1121
  • KovaNovik
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #10 Dátum: 2016. január 10. - 17:57:49 »
+1 Show voters
Lehet meg kéne próbálni sima aposztróffal is és hagyni az okoskodásomat. :D

Nem elérhető myke

  • 213
    • Profil megtekintése
Bemutatkozás rendszer
« Válasz #11 Dátum: 2016. január 10. - 19:28:12 »
0 Show voters
Pedró, sajnos így sem jó. :(

Dupla hozzászólás automatikusan összefûzve. ( 2016. január 10. - 20:41:24 )

Na. Picit másképp, de sikerült megoldani. Nagyon sokat segítettél, még az SQL tanulásában is.
Köszi a segítséget. : :)
« Utoljára szerkesztve: 2016. január 10. - 20:41:24 írta myke »

Bemutatkozás rendszer
« Válasz #12 Dátum: 2016. január 10. - 21:22:09 »
0 Show voters
[gmod]A téma zárva volt \'megoldatlanként\'. Legközelebb kérlek simán a \'Téma megoldva\' gombra menj.[/gmod]
www.twitch.tv/almightymartin

Az év STAFF tagja - 2015
Az év RP szervere - 2015 - [rc-rp.hu]

Red County Role Play [rc-rp.hu] - Tulajdonos
Project San Andreas [psa.hu] - Főadminisztrátor
See MTA LV [see-game.com] - Admin 4

 

SimplePortal 2.3.7 © 2008-2024, SimplePortal