Ai un mediu care compilează sursa nemodificată. Acum poți face prima schimbare în codul C++. Tentația e să începi cu ceva „important”: dropul, daunele, un sistem nou. Nu o face. Prima modificare trebuie să fie **mică, vizibilă și fără legătură cu economia sau cu datele jucătorilor**. Așa înveți tot drumul (editare, compilare, deploy, test, rollback) fără să riști nimic. Vom traduce mesajul unei comenzi de GM.
cmd_gm.cpp textul afișat de comanda /who, îl schimbi într-o copie a sursei, verifici că ai schimbat un singur rând, compilezi game, îl pui pe serverul de test și scrii /who în joc. Dacă vezi noul text, ai parcurs tot drumul.Nivel: Avansat. Ce trebuie să știi înainte: compilarea game reușită cu sursa nemodificată, cum pui binarele pe server și un cont GM pe serverul de test (vezi conturile GM și permisiunile).
Cuvinte pe care le vei întâlni
| Cuvânt | Ce înseamnă |
|---|---|
| Funcție | O bucată de cod cu nume, care face un lucru anume. Aici: do_who, care răspunde la comanda /who. |
ChatPacket | Funcția care trimite un mesaj în chatul unui jucător. |
%d | Un „loc gol” în text, unde programul pune un număr. Nu îl șterge. |
| diff | Comandă care arată diferențele dintre două fișiere, rând cu rând. |
Ce schimbăm
În sursa verificată, comanda /who arată câți jucători sunt online. Codul ei e în game/src/cmd_gm.cpp:
ACMD(do_who)
{
int iTotal;
int * paiEmpireUserCount;
int iLocal;
DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal);
ch->ChatPacket(CHAT_TYPE_INFO, "Total [%d] %d / %d / %d (this server %d)",
iTotal, paiEmpireUserCount[1], paiEmpireUserCount[2], paiEmpireUserCount[3], iLocal);
}Pe românește: funcția numără jucătorii (total, pe fiecare din cele 3 regate și pe acest core), apoi trimite în chat textul dintre ghilimele, punând numerele în locul celor cinci %d, în ordine. Noi schimbăm doar textul, nu și numerele.
În tabelul de comenzi din cmd.cpp, /who e permisă doar pentru nivelul de GM GM_IMPLEMENTOR, deci îți trebuie un cont GM cu acest nivel.
Pasul 1: Lucrează pe o copie, cu istoric
cp -Rp /usr/home/sursa /usr/home/sursa-who
cd /usr/home/sursa-who
cp -p game/src/cmd_gm.cpp game/src/cmd_gm.cpp.origAi acum o copie separată a sursei și o copie a fișierului original. Dacă folosești Git (vezi modificări sigure), fă un commit înainte de schimbare. Nu pune niciodată parole sau fișiere CONFIG reale în Git.
Pasul 2: Găsește rândul
grep -n "Total \[%d\]" game/src/cmd_gm.cppgrep -n caută textul și îți spune numărul rândului. \[ înseamnă „paranteza dreaptă, ca atare” (altfel grep o interpretează altfel).
Ce ar trebui să vezi: un singur rând, cu numărul lui. Dacă vezi mai multe sau niciunul, sursa ta e diferită; caută do_who și citește codul.
Pasul 3: Schimbă textul, fără să strici fișierul
Descarcă cmd_gm.cpp cu WinSCP și deschide-l în Notepad++. Înainte să scrii ceva, uită-te în bara de jos la codificare. Fișierul acesta are comentarii vechi în coreeană. Nu-l converti în alt encoding și nu folosi „Convert to UTF-8”.
Schimbă doar textul dintre ghilimele:
ch->ChatPacket(CHAT_TYPE_INFO, "Jucatori online [%d] %d / %d / %d (pe acest core %d)", Reguli:
- păstrează exact cinci
%d, în aceeași ordine; - fără diacritice în cod: textul ajunge în client cu codificarea serverului, iar ă, ș, ț pot apărea ca semne ciudate;
- nu atinge ghilimelele, virgula și restul rândului.
Salvează și urcă fișierul înapoi.
Pasul 4: Verifică ce ai schimbat
diff -u game/src/cmd_gm.cpp.orig game/src/cmd_gm.cppCe ar trebui să vezi: exact un rând cu - (cel vechi) și un rând cu + (cel nou). Dacă vezi zeci de rânduri schimbate, editorul a modificat codificarea sau sfârșiturile de rând. Pune originalul înapoi (cp -p game/src/cmd_gm.cpp.orig game/src/cmd_gm.cpp) și reia pasul 3 cu mai multă grijă.
Pasul 5: Compilează și pune pe test
Librăriile nu s-au schimbat, deci compilezi doar game:
cd /usr/home/sursa-who/game/src
gmake 2>&1 | tee /usr/home/build/game-who.logFără gmake clean, se recompilează doar cmd_gm.cpp, apoi se face legarea. Durează mult mai puțin decât prima dată. Verifică fișierul cu file și sha256, apoi pune-l pe serverul de test exact ca în lecția despre deploy.
Pasul 6: Testează în joc
Intră cu contul GM pe serverul de test și scrie în chat:
/whoCe ar trebui să vezi: Jucatori online [1] 1 / 0 / 0 (pe acest core 1) sau ceva asemănător, după câți sunt conectați și în ce regat. Apoi fă și testul scurt obișnuit: login, monstru, NPC, schimbare de canal. Chiar și o schimbare de text poate ascunde o greșeală de compilare.
Cum revii
Pe serverul de test: oprești, pui la loc game-ul vechi, pornești. În sursă: pui la loc cmd_gm.cpp.orig (sau revii la commitul anterior în Git).
Abia după asta
Când ai parcurs drumul o dată fără emoții, poți încerca o schimbare de logică, tot pe test: de exemplu o valoare care afectează doar un monstru de test. Ține minte regula din prima lecție a capitolului: dacă se poate face din fișiere TXT sau questuri, acolo e locul ei.
Greșeli des întâlnite
- Ștergi, adaugi sau muți un
%d. Mesajul afișează numere greșite, iar un%dîn plus (fără număr care să-i corespundă) poate chiar opri serverul. - Pui diacritice în textul din cod. Apar semne ciudate în chat.
- Salvezi cu altă codificare și strici comentariile din tot fișierul.
- Faci prima modificare pe drop sau pe daune. Dacă greșești, afectezi economia.
- Modifici direct sursa „bună”, fără copie.
Întrebări frecvente
Pot schimba la fel și mesajele care apar la jucători?
Da, după aceeași metodă. Unele mesaje vin însă din fișiere de traducere ale serverului sau ale clientului, nu din cod. Caută întâi textul cu grep în sursă și în share/locale.
De ce nu se schimbă mesajul după restart?
Verifică trei lucruri: ai compilat copia corectă a sursei, ai pus pe server binarul nou (compară sha256) și toate core-urile folosesc acel fișier.
Trebuie schimbat și clientul?
Nu. Textul e trimis ca mesaj de chat obișnuit. Clientul îl afișează fără să știe ce scrie în el.
Ce urmează
Ce faci când serverul cade? Învață depanarea unui crash cu gdb. Toate lecțiile sunt în lista tutorialelor Metin2.
Server Metin2 gata de joc
Găzduire Metin2 în România, cu instalare de serverfiles, bază de date MySQL și protecție Anti-DDoS inclusă.