Jump to content
Rpg²S Forum

Teoria Programmazione Giochi Online


Keroro
 Share

Recommended Posts

Sono insonne, sono le 2.30, e quindi scrivo qualche parola di getto piuttosto che perdere tempo sui siti hot, magari quello che scrivo può essere utile a qualcuno, mi sento abbastanza ispirato.

Ciò non toglie che domani da riposato e sano non possa correggere e magari estendere ciò che scriverò :D

 

Molti vorrebbero creare il loro mmorpg o anche solo un gioco online ma sono spaventati da un mondo che non conoscono completamente, la network programming!

Cercherò quindi in questa miniguida di illustrare i concetti principali della programmazione dei giochi web, frutto di diverse mie prove che per motivazioni diverse non sono mai state concretizzate.

 

Innanzitutto la motivazione, perché si vuole creare il gioco online?

Questa domanda ha una sola risposta, a cui si può dare una interpretazione positiva o negativa a seconda della visione del mondo.

Innanzitutto la risposta è... (provate a indovinare)

 

La Sfida

 

Il giocatore si sente vivo a ownare un'altra persona, è un meccanismo istintivo, naturale e MOOOLTO soddisfacente.

Ma perché è così soddisfacente?

a) Siamo/Siete una sega a creare IA appaganti/equilibrate

b) Il giocatore si troverà di fronte sempre nuove sfide/avversari mentre in un gioco offline finita la storia finito il divertimento => gioco nel cestino

 

Esistono, al giorno d'oggi, 3 alternative per creare un gioco online

a) Via Client/Server

b) Via Browser

c) Ibrido

 

Appunti:

I sistemi b e c offrono o una grafica scarna o una dinamica lenta ma maggior semplicità di realizzazione

 

Nota: Non lasciatevi incantare, le applet java ricadono nel meccanismo client/server

 

Data la mia poca esperienza con il php nel gestire alternative alle sessioni (qui bisognerebbe far intervenire esperti tipo dax) vi parlerò solo dell'alternativa a

 

Meccanismo Client/Server

Esistono migliaia di giochi famosissimi che rientrano in questa famiglia, ad esempio Wow, Ragnarok Online, Gunbound e il 99.9% degli MMORPG che non sto a citare perché non mi frega, ma anche tutti quei giochi fatti per 2, 4, 8, 10 giocatori.

 

Ora dovrei entrare in modalità pallosa e spiegare i vari tipi di reti ad anello, ecc.. ma lo evito volentieri

La maggior parte dei giochi online commerciali funziona in questo modo:

esiste da qualche parte nel mondo una farm, ovvero una serie di computer collegati tra di loro, che fungono da server (per giochi amatoriali basta un pc :) )

un giocatore invece è un client

 

La regole classica di costruzione di un gioco online, favorita anche dall'aumento negli anni della banda di down/up (oltre e soprattutto per logiche di sicurezza), sono che il client può dialogare solo ed esclusivamente con un/i server e quindi mai direttamente su altri client.

I messaggini privati che mandate al vostro amico tramite ragnarok passano comunque dal server.

 

Il server quindi sarà un programma che gestisce ogni canale di comunicazione con i client e da bravo postino dovrà reindirizzare i messaggi

 

Il client invece dovrà essere abbastanza aggiornato dal server da permettere una buona esperienza di gioco, e ogni tanto dovrà inviare sue notizie

 

Tipo di comunicazione e dinamiche di gioco

Come al solito ci troviamo di fronte ad una vasta letteratura che non fa che confondere l'apprendista, se devo creare client e server a che santo mi devo votare? al protocollo tcp/ip o al protocollo udp? seppure vi affidate ad una libreria che automatizza gran parte delle procedure, la scelta stilistica ha delle ripercussioni molto profonde sulla giocabilità!

 

Innanzitutto se non sapete neanche cosa sono i protocolli tcp/ip e udp vi do qualche pillola.

Prendete come assioma che l'informatica va avanti a standard, perché senza standard non sarebbero possibili forme di comunicazione (l'italiano è un esempio di standard).

Un protocollo è un insieme di regole formali (o ben-definite ergo comprensibil'inequivocabili) che in questo caso regola la trasmissione (invio e ricezione) di dati attraverso due nodi della rete (sia essa locale o globale).

La comunicazione vuole un mittente, un destinatario ed un messaggio.

Nel caso del protocollo tcp/ip il mittente e il destinatario sono in qualche modo connessi virtualmente nei due sensi (ovvero entrambi possono agire sia da mittente che da destinatario) ed i messaggi arrivano sempre e comunque (eccetto perdite di pacchetto che hanno una distribuzione poissoniana come modellizazione, quindi molto rare), ed arrivano nell'ordine in cui sono stati inviati (cosa molto importante!),

Il difetto del protocollo tcp/ip è la pesantezza degli header (intestazioni) dei pacchetti (la distribuzione dei messaggi avviene per frazioni dette pacchetto di non so, qualche centinaio di kb di lunghezza) che provoca un carico in più per la rete (simulare la connessione tra le due macchine richiede risorse, la non fallibilità del sistema richiede pacchetti aggiuntivi di conferma di avvenuta ricezione)

 

Il protocollo udp invece è più snello nel senso che non avviene una connessione tra mittente e destinatario, ogni messaggio inviato funziona come un aeroplanino di carta, non c'è bisogno che tu e il destinatario abbiate un canale di comunicazione, non è garantito che il messaggio arrivi e se mandi più messaggi o aeroplanini, non è detto che arrivino in ordine, il vento può averli mischiati nel frattempo.

Un bel dito in culo, noterete voi :Ok: .

Chiaramente sì, ma offre dei vantaggi considerevoli quali velocità e non carica eccessivamente la rete.

 

Come usare udp?

Sta al programmatore client/server definire delle regole per marchiare i messaggi udp per poterli riordinare e magari richiedere se smarriti (e qui si aprirebbe una larga parentesi sulle strategie per marchiare un pacchetto e al contempo avere una comunicazione "sicura")

 

Perché usare udp?

A questa domanda personalmente risponderei per quasi nessun motivo, perché al giorno d'oggi con la banda down/up disponibile a meno di giochi next gen programmati col culo usare udp non ha particolari vantaggi, la teoria invece vuole che udp sia usato per tutti quei processi in cui il tempo di risposta è critico, quindi quando la dinamica del gioco è molto veloce (es. sparatutto o mmorpg) se non fosse che la maggior parte degli mmorpg commerciali, seppur con centinaia di migliaia di utenti, tipo WOW, usi il protocollo tcp/ip (ma loro hanno una mega farm ._.) (anche Ragnarok Online usa tcp/ip ma l'emulatore server ovvero eathena è programmata un po' male quindi spesso e volentieri lagga (non parliamo della cacca nota come aegis :D))

 

Quindi ci conviene usare solo tcp/ip?

La risposta è NI.

La soluzione ideale sarebbe un modello ibrido sia tcp/ip che udp, su connessione tcp/ip si fanno passare i dati sensibili mentre su udp e con maggiore frequenza si inviano i dati a dinamica veloce (esempio posizione+velocità del personaggio), ma è consigliato solo per server con taaaaaaaante persone visto che lo sbatti è considerevole!

Per server con una stima di giocatori inferiore a 500 giocatori mi prendo la responsabilità di dire che basta l'uso del protocollo tcp/ip (oltre che un cervello acceso).

 

Bene, ho scelto (volontariamente XD) di usare il protocollo tcp/ip, ma come funziona in dettaglio?

 

Iniziamo col dire che, trascurando le reti locali, ogni macchina è identificata da un indirizzo ip ed ogni macchina ha a disposizione 65536 porte.

 

L'indirizzo ip (v4, l'ipv6 può andarsi a farsi friggere) può essere rappresentato da una serie di 4 numeri grandi un byte (da 0 a 255) separati da un . es. 214.0.232.12

 

Cos'è una porta?

Immaginate una porta.

Ecco...

 

Il server piazza uno dei suoi nipoti dietro una prefissata porta ad ascoltare, Arriva il giocatore/client, che ha bisogno di qualcosa, all'indirizzo ip trovato sul biglietto da visita (homepage) del videogioco, bussa alla porta prefissata, il nipote del server, che aveva ascoltato, gli apre (è un po' pollo, per filtrare a priori servono le iptables) e, in genere, il giocatore parla per magari presentarsi.

Se al server sta bene quello che dice magari risponde con un saluto ed un piccolo aggiornamento e lascia la porta aperta per ulteriori discussioni, altrimenti può benissimo mandarlo a cagare se è un testimone di geova.

Se ci fosse un solo giocatore con un nipote me la caverei bene...

 

Il problema è che i giocatori sono molteplici e i figli del server non hanno trombato come conigli (oltre al fatto che ho appena 65k porte :sisi: ) quindi io server non avendo un nipote per ogni porta, decido di usare un'unica porta (o un paio ma dimenticatelo) per l'accettazione (ovvero come portineria) ma creo, nel momento in cui accetto la visita, un collegamento psichico diretto, tra me e il client, a cui do il nome di Socket, che in soldoni non è altro che una comoda astrazione che simboleggia il percorso tra mittente e destinatario o viceversa. (il doppio collegamento sopra citato nella spiegazione di tcp/ip)

Ricapitolando da server:

Metto un nipote in ascolto su una determinata porta;

Se bussano alla porta dell'accettazione, creo un collegamento con loro (Socket);

Vedo chi sono:

se non mi piacciono, li butto la porta in faccia distruggendo il Socket al volo

altrimenti

conservo in qualche modo le informazioni che mi danno, magari associando il nome con cui si sono presentati (e che ho ritenuto valido) con il Socket, in modo che nelle successive comunicazioni non avrò problemi ad identificare da chi ricevo il messaggio o a chi lo mando.

In programmatichese questo si fa in molteplici modi, a partire da due array, uno di Socket e uno di Stringhe dove a stesso indice corrisponde stesso utente, o con UNA o PIÙ liste, dinamiche o meno, di struct ad esempio (adattato da un mio sorgente in c, ultimamente sono su linux, che usa gli int per identificare i socket):

#ifndef WIN32
typedef int Socket;
#endif
typedef struct client{
Socket * sock;
char * nome;
struct client * next;
}Client;

WOW del codice inutile! :)

 

Secondo grande dilemma

Siamo arrivate al secondo grande dilemma, dopo la scelta forzata di tcp/ip XD

Qui però non esiste una strada giusta ed una sbagliata...

Il problema è, io SERVER ho capito che devo memorizzare ogni collegamento e magari associarlo ad una struttura dati che memorizza anche informazioni (che in un mmorpg possono essere anche posizione, razza, sprite, stato, ecc...) ma esistono diversi TIPI di collegamento e di conseguenza diversi MODI di implementarlo (pur rimanendo entro i confini del tcp/ip)

Compaiono quindi nuovi paroloni quali sincrono, asincrono, threaded.

Cosa significano?

Sincrono ed asincrono si riferiscono al modo in cui il destinatario riceve il messaggio. La modalità sincrona significa che il destinatario rimane con la bocca aperta e saliva calante (aka modalità Homer&Donuts) fino a quando non riceve il messaggio da parte del destinatario, e se non arriva è possibile che rimanga per le mani in mano fino alla fine del programma!

La modalità asincrona significa invece che faccio una corsetta fino al Socket (il mio collegamento visto come corridoio virtuale), vedo se c'è un pacchetto fuori dalla porta, se non c'è continuo la mia corsetta nel sbrigare le altre faccende di casa (magari controllando gli altri socket).

E' chiaro che, se non avessimo a disposizione particolari tecnologie, l'unico modo per fare un gioco sarebbe tramite socket asincroni perché avendo più client non possiamo rimanere incantati su un solo Socket!

Esiste però una parola magica chiamata thread, che voi di rpgmaker potete immaginare come un processo parallelo che non rallenta tutto perché è DAVVERO parallelo, una sorta di schiavetto, che al contrario di nostro nipote non ci viene a chiamare appena bussa qualcuno ma che esegue in autonomia quello che c'è da fare, possibilmente senza intralciarci, e che ha a disposizione la nostra casuccia (le variabili globali)

Un programma quindi può creare tanti thread o sottoprocessi che andranno ad occupare una area ben definita in memoria (quindi come limite al numero di thread da creare dovete considerare la memoria ram e la velocità della cpu del server) e eseguiranno operazioni contemporaneamente al server, possibilmente senza scornarsi ovvero dovranno cercare di non accedere contemporaneamente alla memoria condivisa (per questo esistono i semafori, mutex e altre diavolerie).

 

Esistono quindi tante vie di implementare un server:

1a) Usare socket asincroni, creo il mio bel listone giordano e controllo

1b) Usare socket asincroni, immagazzinati in strutture e funzioni che fanno il lavoro per me (select() )

2) Usare socket sincroni+ thread, ogni thread è un bocc'aperta

3) MIX (provate a pensarci)

 

La soluzione 1a è la più usata in applicazioni commerciali che hanno a disposizione farm

La soluzione 1b è il modo più semplice per ottenere un buon server < 400 utenti (butto la cifra a naso, poi dipende da quanto si è programmato bene)

La soluzione 2 porta ad un grande spreco di memoria ed è fatta solo dai ragazzini :)

La soluzione 3 è l'unico modo per avere un server competitivo con le applicazioni commerciali senza dover gestire una farm di server

 

 

[-----------------]

 

Per stanotte è tutto, si sono fatte le 6 e ho passato 3 ore e rotti qui su :)

Mi scuso per il linguaggio volgare, ma volevo arrivare a tutti.

Penso che ci sarà un seguito presto, sia per approfondire il MIX lasciato in sospeso sia per introdurre nuovi argomenti, il tutto dettato anche in base al vostro feedback (ovvero risposte a questo topic), spero di guadagnarmi qualche rens così posso aprirmi una botteguccia :E

Se non capite qualcosa o volete ulteriori semplificazioni sugli argomenti trattati, non avete che da chiedere, più avanti magari metterò qualche codice più esplicativo ma volevo rimanere caotico neutrale perché non è detto che dobbiate scendere fino a livello socket per fare un gioco online poiché potete benissimo usare una libreria di terzi, ma mi premeva darvi almeno un rudimentale metro di giudizio

 

ByeZ

Edited by Keroro

I Miei Script:
Salva Schermata (3 Aprile 2012)
Attacco Personalizzabile (2 Aprile 2012)
Keyboard Input (Porting) (17 Marzo 2012)
Continua...

Link to comment
Share on other sites

Wow, grande °°

alcune cose le sapevo, ma mi è stato utilissimo il chiarimento su udp e tcp/ip °O°

 

L'ultima parte mi è poco chiara, da quando hai tirato fuori sti cosi:

1a) Usare socket asincroni, creo il mio bel listone giordano e controllo

1b) Usare socket asincroni, immagazzinati in strutture e funzioni che fanno il lavoro per me (select() )

2) Usare socket sincroni+ thread, ogni thread è un bocc'aperta

3) MIX (provate a pensarci)

spero si chiarisca quando continui XD

Progetti:

 http://i.imgur.com/jmLkIqi.png

http://i54.tinypic.com/2rh4ojq.png

https://github.com/ProGM

 

Crea anche tu il tuo gioco per Game Boy!
http://rpg2s.net/gif/SCContest3Oct.gifhttp://www.rpg2s.net/img/fablecontest1st.pnghttp://i43.tinypic.com/1zokd2s.png


http://i.imgur.com/BEu6G.gif

http://i.imgur.com/H1ARhq7.gif

http://i.imgur.com/Af6ijZN.gif

AOT: Associazione Odiamo la Telecom:

http://i.imgur.com/aYJs89E.png

"4 gattini... 4 stelline... E le 4 paperelle non ci stavano :3"

Flame


http://i30.tinypic.com/i27ypj.png

Link to comment
Share on other sites

Davvero un bel tutorial spiegato in maniera semplice ed efficace, l'unica parte che potrebbe risultare meno chiara per chi non conosce già l'argomento(non è il mio caso) è quella sull' I/O sincrono asincrono e multiplex(in pratica quella su cui ha dubbi anche ProGM).

Se hai intenzione di continuare la trattazione mi farebbe moolto piacere se ci fossero più esempi concreti con codice( al corso dell'uni non ci hanno fatto approfondire molto la parte pratica), per esempio come utilizzare le socket su winzozz senza senza scomodare java (ora che ci penso forse si potrebbe provare con cygwin, ma non ne sono sicuro).

Fiero membro della:

[img]http://img87.imageshack.us/img87/9409/yumenosoftgw5.png[/img]

[url="http://rpg2s.net/forum/index.php?showtopic=1529"][img]http://img225.imageshack.us/img225/8845/tenshibanxd5.png[/img][/url] [color="#0000FF"][b]A [i][url="http://yumeno.altervista.org/"][color="#9932CC"]YumeNo-Soft[/color][/url][/i] Production[/b][/color]
Link to comment
Share on other sites

Bel tutorial però a quanto pare stai un pò indietro su struttura generale, ora come ora quasi tutti i mmorpg commerciali si appoggiano a un database (mysql di solito) e soprattutto grazie a quest'ultimo la velocità di modifica di informazioni è velocissima. Io sto lavorando (unico italiano..:( ) al progetto open source di VbGore (engine per la realizzazione di mmorpg).

Risultati Contest
http://rpg2s.net/gif/SCContest1Oct.gif-http://rpg2s.net/gif/SCContest1Oct.gif-http://rpg2s.net/gif/SCContest1Oct.gif-http://rpg2s.net/gif/SCContest1Oct.gif-http://rpg2s.net/gif/SCContest2Oct.gif - 3° Posto Clou Contest

Link to comment
Share on other sites

SQL

è una questione che ho trascurato volutamente, sono consapevole che i database siano largamente usati, ma non aveva senso mettermi a spiegare questo se non si sa neanche come organizzare il resto :)

anche perché dovrei iniziare a parlare del linguaggio SQL, delle selezioni, della possibilità di avere più database e quindi di fare join mirati ad ottenere tutti i dati che servono, ma esulerei troppo dal discorso!

Lasciando quindi perdere i dettagli intimi che chiunque potrebbe leggere in un manuale, dedicherò (o forse anticiperò la trattazione, nella mia testa non so se e quando sarebbe avvenuta) un po' di tempo ad i database SQL, dopo averti risposto :D

 

non mi pare di essermi espresso male con la faccenda delle struct del client non parlando esplicitamente di database poiché in memoria una struct per il client SERVE quando devi manipolare dei dati, lavorare direttamente facendo query SQL è dannatamente lento!

 

Legenda

< significa riceve in input

> significa invia come output

? posto vicino ad operatore significa eventualmente

db significa database

 

::tiziocaio combatte con slime

server < tiziocaio da query sql db dei personaggi (joinato magari con quello degli account) (se non già presente in memoria!)

server < slime da query sql db dei mostri (e se ci sono solo 10 tipi di mostro, concordi anche tu che fare un database un po' mi puzza ;) )

::finché la battaglia imperversa

server > calcoli al client

client > aggiorna il mondo al giocatore

client <? riceve input giocatore

server <? cambio di strategia del client

::fine battaglia

server ?> exp al client o messaggio di morte o fuga dalla battaglia (una battaglia può finire in tanti modi)

client <? riceve exp e/o aggiorna dati interni

server ?> aggiorna tiziocaio in db

 

è su questo che mi soffermerei, non è così immediato da capire che io non devo aggiornare il database dopo ogni scontro perché è una operazione esosa (se aggiorno e il client compie un'altra azione 1 secondo dopo devo riscaricarmi tutti i dati, di nuovo) e preferisco spesso lasciarmi i dati in memoria (con delle funzioni che tengono traccia magari del timeout e di quanta ram è libera) e magari aggiornare il database ogni 5/15/20/30 minuti o 2 ore (se mi sento spavaldo XD).

Certo ribadirai che per questo piuttosto che tenere in memoria in una struct pg io possa direttamente estrarlo e metterlo in delle struct fatte appositamente per la battaglia ma capisci che questo esula dalla propositività di for dummies e ci si dovrebbe addentrare prima in discussioni tipo:

 

Ha senso usare dei database?

Ha molto senso perché sono tanto facili da gestire (sviluppo sostenibile) e sono consigliati per server che mirano a più di 100 utenti connessi contemporaneamente.

 

Ma quale database devo usare?

C'è l'imbarazzo della scelta a cominciare da MySQL (gratuito per le applicazioni opensource ma penso a pagamento per le applicazioni commerciali), MSSQL, Oracle (se si hanno le possibilità economiche...) o alternative gratuite come PostgreSQL (il migliore tra i free software) o SQLite (un minidatabase piccolo e veloce, naturalmente ha anche lati negativi).

Io consiglio MySQL per la diffusione e se siete alle prime armi, mentre se avete in mente di fare un progettino serio dovete vedere bene i dettagli delle licenze di MySQL e al massimo optare per PostgreSQL

 

Che alternative ho ai database?

Se mi fate questa domanda è perché finora sono stato poco chiaro :)

Un database è una tecnologia dove immagazzinare ordinatamente le informazioni sensibili, a cui possiamo accedere tramite una interfaccia software, ovvero l'elaboratore del linguaggio SQL che interpreta il nostro codice e ci restituisce un risultato.

Dovete immaginare il database come se fosse un altro client attaccato persistentemente al server

 

client <==> server <=!=> database <==> dati

 

dove quel punto esclamativo indica che il legame non si può rompere perché funzionano "a braccetto".

Quello che ci importa quindi è un sistema di accesso ai dati!

E allora potremmo benissimo usare della alternative, dai semplici fogli di testo formattati come ci pare a minidatabase xml.

Ma qui compaiono altre problematiche, perché

 

client <==> server <==> BUCO <==> dati

 

l'interfaccia di accesso ai dati la dobbiamo costruire noi, o tramite le funzioni di sistema o tramite altre librerie e spesso se non ci si pone abbastanza attenzione abbiamo funzioni ancora più pesanti del database o un design cattivo per i dati e per ottenere le informazioni che ci servono o solo paragonarle dobbiamo fare i salti mortali.

Un esempio chiarificatore potete averlo guardando i miei due emulatori preferiti, eathena_SQL e eathena_TXT e vedere come nel TXT ci si incasina notevolmente e per inserire dati o si smania con il txt oppure bisogna scriversi una applicazione mentre nell'alternativa SQL basta una query fatta o dal gestore interno del database, o da un nostro programmino o perfino da uno script in php/asp (e questo velocizza moltissimo lo sviluppo)

 

Spero di aver dileguato altri dubbi, stavolta trattazione breve, non amo particolarmente i database perché scrivo SQL contro voglia XD, eventualmente ci ritornerò una volta approfondito ulteriormente il corpo del server

 

 

Risposte in sintesi

Mazus, come spero di averti fatto capire non sono un neofita nei database ma permettimi di dissentire su

i mmorpg commerciali si appoggiano a un database (mysql di solito) e soprattutto grazie a quest'ultimo la velocità di modifica di informazioni è velocissima
i database RALLENTANO la modifica delle informazioni A FAVORE della semplicità (vuoi comparare le system calls read() write() al lavoro che fa un database? se vuoi scrivo un programmino ad hoc e facciamo un benchmark ma spero che te ne renda conto da solo :) ).

Apprezzo che tu abbia già esperienza quindi spero revisionerai il lato database dei miei post e magari offrirai altri spunti ;)

 

ProGM, era solo un accenno, nel prossimo post lo tratterò in dettaglio ;)

 

Kamahl

per esempio come utilizzare le socket su winzozz senza senza scomodare java (ora che ci penso forse si potrebbe provare con cygwin, ma non ne sono sicuro).

tipico errore delle università il non spiegare accuratamente la struttura degli OS!

 

Winsocket!

i socket non sono una astrazione di java ma un'astrazione offerta già nel sistema operativo!

esistono due tipi di implementazioni per i socket:

Berkeley (spero di averlo scritto bene) e Winsock

le api Berkeley sono implementate in tutti gli OS unix/linux/BSD

le api Winsock sono implementate su Windows a partire da non so che data, forse nel 3.1 erano ancora un pacchetto opzionale, nel 95/98 dovrebbero essere presenti di default

Quindi su windows per avere i socket non devi fare altro che interfacciarti a queste API!

In pillole, se programmi in C per win32, le cose da fare sono queste:

  • #include <winsock2.h>


  • dare in pasto al linker la libreria ws2_32.lib (o libws2_32.a se usi gcc, se ti manca ti posso spiegare come ottenerla)

in questi post io parlerò principalmente avendo come riferimento le Berkeley (sulle quali ho esperienza) tornando di tanto in tanto ad evidenziare le minuscole differenze principalmente SINTATTICHE con Winsock.

La differenza sostanziale è che la libreria (dll) WinSock va Inizializzata (prima) e Deinizializzata (dopo l'uso)

 

All'inizio del programma, dovrai fare qualcosa tipo:

WSADATA wdata;
if (WSAStartup(MAKEWORD(2,2),&wdata)){
//in genere per le piccole applicazioni tratto gli errori così:
//dopo aver definito lo stream error se non definito (non ricordo più com'è in windows XD)
//per maggiori dettagli si può voler chiamare la WSAGetLastError();
fprintf(stderr,"Errore, Impossibile inizializzare libreria Winsock2!");
exit(1);

}
if (! (LOBYTE(wdata.wVersion) == 2 && HIBYTE(wdata.wVersion) == 2)) {
WSACleanup();
fprintf(stderr,"Impossibile caricare Winsock v 2.2!");
exit(2);
}

 

Il primo codice inizializza la libreria winsock versione 2.2, il secondo invece controlla che sia stata davvero caricata in memoria la 2.2, è un check da fare perché le winsock sono bastarde (sotto alcuni punti di vista) e se non hanno a disposizione la versione 2.2 caricano l'ultima versione disponibile (che può essere la 2.0) che magari difetta di qualche funzione o è buggata MA in windows xp e penso superiori (ma l'idea di Vista mi disgusta ;D) è sicuramente presente la libreria aggiornata (quindi non dovete farvi troppe pippe mentali)

 

Per deinizializzare dll e sue strutture basta fare:

WSACleanup();

(eventualmente studiare l'output se si è maniacali :) )

 

Conclusione

Apprezzo molto i vostri commenti positivi :) (e ne aspetto altri anche di altri XD)

Continuate a chiedere approfondimenti e curiosità, presto continuerò il discorso :)

Edited by Keroro

I Miei Script:
Salva Schermata (3 Aprile 2012)
Attacco Personalizzabile (2 Aprile 2012)
Keyboard Input (Porting) (17 Marzo 2012)
Continua...

Link to comment
Share on other sites

Per velocità di modifica delle informazioni non hai capito cosa intendo.

http://www.vbgore.com/wikiimages/1/1d/Use5.png

Nell'engine di VbGore mettiamo a disposizione degli utenti un database MySQL con SQLyog.

SQLyog è un programma interfacciato il quale permette in modo immediato di modificare TUTTE le informazioni del database con semplici click (come puoi vedere in figura). Quindi rinnego nuovamente ciò che dici, con l'uso di un database e un software adatto con un click modifichi velocemente l'informazione...havana e altri (non ricordo) hanno provato questo engine, aggiornavo i dati tramite SQLyog a una velocità impressionante auto-aggiornante del server (senza dover resettare) senza una minima traccia di Lag.

Risultati Contest
http://rpg2s.net/gif/SCContest1Oct.gif-http://rpg2s.net/gif/SCContest1Oct.gif-http://rpg2s.net/gif/SCContest1Oct.gif-http://rpg2s.net/gif/SCContest1Oct.gif-http://rpg2s.net/gif/SCContest2Oct.gif - 3° Posto Clou Contest

Link to comment
Share on other sites

Sapevo che le socket fossero un'astrazione dei sistemi operativi (anche se ancora non ho seguito il corso di sistemi operativi), ma non sapevo proprio su windows come si chiamassero(all'uni non insegnano troppo poco e io ho troppo poco tempo per fare approfondimenti), appena ho un po di tempo faccio qualche prova e se ho dei dubbi chiedo.

Attendo comunque i prossimi post, visto che anche se ho un po di pratica con le Berkeley conoscendo le università credo proprio di saperne fin troppo poco.

P.S.

Domanda da un milione di dollari: ma socket è maschile o femminile? :Ok:

Fiero membro della:

[img]http://img87.imageshack.us/img87/9409/yumenosoftgw5.png[/img]

[url="http://rpg2s.net/forum/index.php?showtopic=1529"][img]http://img225.imageshack.us/img225/8845/tenshibanxd5.png[/img][/url] [color="#0000FF"][b]A [i][url="http://yumeno.altervista.org/"][color="#9932CC"]YumeNo-Soft[/color][/url][/i] Production[/b][/color]
Link to comment
Share on other sites

il socket è maschile

 

Mazus:

il programma per le modifiche immediate non influisce sulla velocità del server!

E' possibile crearne uno anche per un qualsiasi mio formato di file di testo, quindi non vedo dove sia l'innovazione!

Che sia molto più comodo lavorare con il database, non ci piove, anche perché esistono già migliaia di tool vista la diffusione e gli standard proposti mentre usare i file significa crearsi il proprio standard

 

È l'azione di ottenere le informazioni da parte del server che è molto più veloce usando le funzioni di filesystem piuttosto di query sql

In c te la cavi con 3 funzioni: fopen() fgets() sscanf()

L'sql è un linguaggio interpretato, oltre ad inviare la richiesta (delta t1), interpretare la richiesta (delta t2) al tempo che impiego a leggere da disco i dati, che siano poi organizzati con ISAM o InnoDB è trascurabile in questo paragone (delta t3) e poi inviartela tramite socket (delta t4).

Con le funzioni standard di input/output se programmi da cane al massimo impieghi qualcosina in più di delta t3, ma gli altri delta dove li metti?

Pensi che la query sia più veloce perché vieni dall'ambiente di visual basic e quindi ti ritrovi ad affrontare un linguaggio lento ma io parlo di C!

Approfondimento:

nei benchmark migliori è risultato che un exe vb impiega il triplo del tempo per le operazioni di Input/Output di uno in c compilato con gcc che usa le window lib c, differenza che diventa abissale con le glibc e OS linux =)

 

Ora puoi anche non aver trovato lag nelle tue prove, non te lo contesto, ma prova a trovare il numero minimo (o limite) di utenti che ti causa una fissata lag e confrontalo con un server (necessariamente in c/c++) che usa i file di testo, noterai che regge come minimo altri 100 utenti senza arrivare a quella lag

 

Ribadisco, non dico che usare i file sia migliore in assoluto ma ignorare la componente di calcolo del middleware è stupido (l'azione, non la persona, non mi permetterei mai)

I Miei Script:
Salva Schermata (3 Aprile 2012)
Attacco Personalizzabile (2 Aprile 2012)
Keyboard Input (Porting) (17 Marzo 2012)
Continua...

Link to comment
Share on other sites

Tutto quello che vuoi Kero però l'utilizzo di database nelle applicazioni che gestiscono grandi mole di dati è all'ordine del giorno e alla fine anche se ci vuole più temo nell'esecuzione di mysql che di una fopen() credo che la semplicità di sql sia una grossa marcia in più.

Poi per applicazioni di minore entità secondo me si potrebbe fare benissimo affidamento all'xml, che poi secondo me si rileva utile anche come sostituto di mysql per debug e prove variie cioè si può far di tutto senza incasinare nemmeno di un pelino il tuo bel database *_*

Forse si potrebbe anche approfondire questo discorso, l'xml mi affascina parecchio *ç*

TPC Radio Site | Blog | Big-Bug

http://img102.imageshack.us/img102/4332/slackware2userbarok0.gif

http://img141.imageshack.us/img141/1571/nokappams1cf8.png

 

http://i29.tinypic.com/2vijdlh.jpg

Link to comment
Share on other sites

Il database mysql è una grossa limitazione a mio avviso. E' lento, lento lento! Strutturati un database da solo e vedrai che ottieni di meglio. L'unico vantaggio di sql è che è ordinato ed è facile ricavare diversi tipi di dati da un unica query...

Membro Segreto della
Vecchia Guardia del Making [Gif in fase di reload]


SCContest1Oct.gif
gifnatale1.pnggifnatale12.png

Link to comment
Share on other sites

l'Xml infatti è stato proposto come futuro formato di memorizzazione per tutti i database (da mysql a oracle) piuttosto che ISAM, MySam, InnoDB, Postgres e altri per offrire una completa portabilità e di considerare quindi i database solo come mezzo in cui compiere operazioni SQL o particolari proprie estensioni sugli Xml (proposta che però non raggiungerà mai perché ci fanno troppi soldi su).

 

Ma evitando di sognare è possibile benissimo fare copie di backup dei database in Xml se vogliamo provare la via dei file

 

L'XML

pesa un po' di più in termini di kb rispetto ai file di testo ma ha il vantaggio di essere leggibile dall'uomo, standard e facilmente modificabile, inoltre esistono già migliaia di toolkit per leggerli (ora che gli hard disk costano poco è realistico adottare questa soluzione)

avevo comprato un libro ora disperso a casa dei miei genitori, in cui si trattavano approfonditamente le tecnologie xml/xsl/xslt/xpointer/xbase e tanti altri!

È una ottima soluzione per chi decidesse di non usare un database provvisto di SQL perché tramite la tecnologia XSLT è possibile estrarre informazioni in modo paragonabile ad una query.

 

Mi sembra banale e infruttuoso mettermi a descrivere con minuziosità da cosa è costituito un file xml, se volete approfondire cercate in googles

sempre rimanendo della filosofia KISS o Keep it simple vi dico come la vedo io:

Formato xml (trascurando il DTD)

<?xml version="1.0" encoding="UTF-8"?>  
<radice>
<elemento1>
	<nome></nome>
</elemento1>
<elemento2>
	<nome></nome>
	<caratteristiche></caratteristiche>
</elemento2>
  <blablabla></blablabla>
</radice>

 

La grandiosità dell'xml sta nel definire un tree (albero) che si può estendere con profondità infinita al contrario dei database canonici dove c'è solo database -> tabella -> campo.

Un esempio notevole di albero sono le matrioske

dentro ogni bambola può essere visibile 0 o 1 bambola

Il concetto di albero invece è allargato

si parte da un nodo radice

dentro ogni nodo può esserci 0, 1 o più nodi

 

Nella programmazione manipolare alberi ci permette di essere molto più veloci nelle operazioni di ricerca di informazioni

 

XSL

L'XSL è il linguaggio di descrizione del foglio di stile ed incorpora tre linguaggi:

  • XSLT (per lo spiego dopo)
  • XSL-FO (per conversione in pdf/latex)
  • XPath (per boh?)

XSLT

Come già detto l'xslt è la tecnologia per estrarre informazioni, funziona più o meno in questo modo

xml => |MOTORE| 
		| XSLT | => xml (o xhtml o html)
xls/xlst => |______|

 

Esistono versioni di motori XSLT per tutti i linguaggi, sia di scripting e orientati al web come php, asp, python, ruby che in c o java quindi è plausibile usarla nei nostri giochi :)

Una libreria che provai al tempo (5 anni fa) e che ora penso sia cresciuta è Libxslt

 

Esempio di funzionamento

 

Ho il mio database degli account in xml con qualche caratteristica striminzita

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="nomi.xsl"?> 
<lista>
<account>
	<nome>Aldo</nome>
	<sesso>M</sesso>
	<stat>
		<hp>20</hp>
		<str>10</str>
		<dex>53</dex>
	</stat>
</account>
<account>
	<nome>Baglio</nome>
	<sesso>M</sesso>
	<stat>
		<hp>42</hp>
		<str>32</str>
		<dex>29</dex>
	</stat>
</account>
<account>
	<nome>Crucchio</nome>
	<sesso>M</sesso>
	<stat>
		<hp>232</hp>
		<str>32</str>
		<dex>69</dex>
	</stat>
</account>
<account>
	<nome>Sticchia</nome>
	<sesso>F</sesso>
	<stat>
		<hp>10</hp>
		<str>12</str>
		<dex>1</dex>
	</stat>
</account>
<account>
	<nome>Zaino</nome>
	<sesso>M</sesso>
	<stat>
		<hp>30</hp>
		<str>55</str>
		<dex>44</dex>
	</stat>
</account>
</lista>

 

Costruisco un file (magari è meglio renderlo dinamico ovvero generarlo da codice e magari lasciarlo in memoria senza salvarlo sull'hd se non sono di fronte a richieste standard) per estrarre quello che mi serve.

in questo caso mettiamo che mi servono tutti i nomi :)

<?xml version="1.0" encoding="UTF-8"?>  
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

		<xsl:template match="/">	<!-- Applica questo template al nodo radice indicato dal carattere / -->
				<nomi>
				  <xsl:apply-templates>	<!-- Richiama e applica gli altri templates -->
				  </xsl:apply-templates>
				</nomi>
		</xsl:template>

		<xsl:template match="account">	<!-- Quando trova un nodo account applica questa regola -->
			<xsl:value-of select="nome"></xsl:value-of>
		</xsl:template>

</xsl:stylesheet>

 

Ora che ho i due input mi manca il motore per generare l'output, ho fatto due prove, la prima, pallosissima da scrivere, l'ho fatta in C (non riporto il codice completo ma pezzi)

 

Accenno in C e Libxslt

 

//montagna di include..
extern int xmlLoadExtDtdDefaultValue;
...
xmlDocPtr mioxml, risultato;
xsltStylesheetPtr stile = 0;
const char ** parametri;
parametri = (char **)malloc(sizeof(char*));
parametri[0] = 0;

xmlSubstituteEntitiesDefault(1); //sostituire le entità (un casino da spiegare XD)
xmlLoadExtDtdDefaultValue = 1;
mioxml = xmlParseFile("accounts.xml");
stile = xsltParseStylesheetFile("nome.xsl");
risultato = xsltApplyStylesheet(stile,mioxml,parametri);
free(parametri);

 

 

La seconda invece l'ho fatta in Ruby mediante Ruby/XML e Ruby/XSLT (esempio FUNZIONANTE!!!)

 

require 'xml/libxml'
require 'xml/libxslt'

elaboratore = XML::XSLT.new 
elaboratore.xml = "accounts.xml"
elaboratore.xsl = "nomi.xsl"
nomi = elaboratore.serve
print nomi

 

provate per credere, stamperà come ouput

<?xml version="1.0"?>
<nomi>	
	Aldo
	Baglio
	Crucchio
	Sticchia
	Zaino
</nomi>

 

(se serve nell'xsl si può benissimo aggiungere un tag separatore ;) )

 

vi è piaciuto l'esempio :D?

 

..........

 

Alternative a XML per il data storage

Ci sono migliaia di alternative possibile al data storage tramite xml, una che mi sembra interessante è tpl che offre una serializzazione dei dati con la mission di avere le operazioni di lettura e scrittura veloci, ma comunque per un progetto importante conviene affidarsi a:

  • propri standard di file testuali/binari
  • xml
  • databases

------------------------------------------

 

Sviluppo di un server MMORPG

Tornando nel tema principale, come avete visto sono stato molto sbrigativo riguardo i modi in cui è possibile implementare il server, facendo l'elenco soltanto degli argomenti basilari ma di basso livello piuttosto che entrare in profondità su temi AVANZATI di networking.

Adesso non ho tempo di riprendere la trattazione in profondità ma sfrutto l'argomento Xml per introdurre un nuovo metodo ad alto livello

 

RPC

RPC è la sigla che identifica la Remote Procedure Call e identifica la tecnologia per la quale da una data macchina possiamo chiamare una funzione/procedura di un'altra macchina.

E' un'idea geniale ma comporta anche una notevole organizzazione soprattutto nel design dell'applicazione PERÒ bisogna ricordare che si tratta di meccanismi ad alto livello che mascherano il livello socket e spesso aumentano i problemi piuttosto che semplificarli,infatti è da usare con cautela perché aumenta il carico del server (la funzione viene eseguita dal server e l'output viene rimandato indietro) ed è quindi idoneo a chiamate con risposte precise come ad esempio in automatica mi sono trovato in un laboratorio dove il pc era collegato ad un sensore che misura la temperatura, avrei potuto usarlo come server per controllare l'esperimento da casa ed una RPC sarebbe stata l'ideale per controllare la temperatura

 

Nel mondo degli mmorpg le rpc sono ideali soprattutto per smaltire il login, creando un login server che funga da filtro ovvero in caso di autenticazione fallita chiude la porta al client, nel caso di autenticazione riuscita reinderizza il client al vero e proprio programma server che può stare benissimo su un'altra macchina (o su più macchine) se siamo una software house e abbiamo a disposizione un cluster

 

Implementazioni

Ci sono diverse implementazioni delle RPC, una libreria famosa, meravigliosa ed economica è sicuramente la RakNet (che però è per c++ e non per c :( ) ma se ho deciso di parlarne è perché ho collegato l'Xml alla XML-RPC-c che implementa il discorso precedente tramite messaggi di richiesta e risposta in formato xml che viaggiano nella rete attraverso il protocollo http.

 

Forse più tardi vi farò un esempio su XmlRpc

 

Per ora ditemi che cosa ne pensate di questo tutorial :) e per domande/dubbi ci sono sempre, non scappo

Edited by Keroro

I Miei Script:
Salva Schermata (3 Aprile 2012)
Attacco Personalizzabile (2 Aprile 2012)
Keyboard Input (Porting) (17 Marzo 2012)
Continua...

Link to comment
Share on other sites

Fai schifo, io accenno solo ad xml è mi dice tutta la vita, morte e miracoli di xml.

Cmq tornando in tema secondo me potresti apliare il discorso sull'xml sviluppando una specie di lib. per la gestione di un database interamente mantenuto da file xml, potrebbe venir fuori qualcosa di particolarmente interessante per la creazione di mmorpg, d'altro canto i mmorpg gestiscono dati a non finire quindi una gestione ottimale di quest'aspetto sarebbe da studieggiare con più attenzione ;O;

TPC Radio Site | Blog | Big-Bug

http://img102.imageshack.us/img102/4332/slackware2userbarok0.gif

http://img141.imageshack.us/img141/1571/nokappams1cf8.png

 

http://i29.tinypic.com/2vijdlh.jpg

Link to comment
Share on other sites

sono pigro e non mi imbarcherò in un progetto che non riuscirò a portare a termine ;_;

dopo il mio post di prima basato soprattutto su reminiscenza, mi sono documentato e ho ripreso a studiare le diverse tecnologie X (hot :Q_) e mi sono accorto con grande piacere che l'Xpath di cui non ricordavo niente è studiato per le ricerche e soprattutto che sopra questo (insieme ad XSLT e XLink) hanno creato XQuery 1.0 (diventato w3c raccomandation 1 anno e 5 giorni fa !!!) che viene presentato come il linguaggio per interrogare l'xml!

 

(/me si lecca i baffi e inizia a studiare)

Edited by Keroro

I Miei Script:
Salva Schermata (3 Aprile 2012)
Attacco Personalizzabile (2 Aprile 2012)
Keyboard Input (Porting) (17 Marzo 2012)
Continua...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...