Day.png);">
Apprendre


Vous êtes
nouveau sur
Oniromancie?

Visite guidée
du site


Découvrir
RPG Maker


Apprendre
RPG Maker

Tutoriels
Guides
Making-of

Dans le
Forum

Section Entraide

Jeux: puie z / Jeux: Citymaime - Chapitre 1 / Jeux: Mer, îles et fous / News: Du neuf dans le making / News: Muma|Rope est disponible en (...) / Chat

Bienvenue
visiteur !




publicité RPG Maker!

Statistiques

Liste des
membres


Contact

Mentions légales

385 connectés actuellement

30732277 visiteurs
depuis l'ouverture

2255 visiteurs
aujourd'hui



Barre de séparation

Partenaires

Indiexpo

Akademiya RPG Maker

Blog Alioune Fall

Fairy Tail Constellations

Le Temple de Valor

Hellsoft

Kingdom Ultimate

RPG Maker - La Communauté

Planète Glutko

Tous nos partenaires

Devenir
partenaire



RGSS Network

[Programmation Web] Adaptation du module réseau de SFML 2.3 faite en C++. Contient les socket TCP, UDP et des requêtes HTTP. Pour XP, VX et Ace.

Script pour RPG Maker XP
Ecrit par Otruch
Publié par Otruch (lui envoyer un message privé)
Signaler un script cassé

❤ 0

Auteur : Otruch
Logiciel : RPG Maker XP, VX et Ace
Nombre de scripts : 3

Bonjour à tous,

j'ai adapté le module réseau de SFML 2.3 pour le rendre compatible avec le RGSS. Testé sur RPG Maker XP, elle devrait fonctionner pour les autres. Cette implémentation est uniquement pour les scripteurs, elle ne vous servira à rien si vous ne savez pas scripter.

Ce module contient :
- socket TCP : permettent de communiquer avec un serveur TCP. La communication est lente, mais fiable. Elle permet par exemple d'implémenter un système de combat en ligne en tour par tour.
- socket UDP : permettent de communiquer avec un serveur UDP. La communication est rapide, mais peut avoir des erreurs. Elle permet par exemple de faire un salon avec plusieurs joueurs, afficher les coordonnées/mouvements de chaque joueur. Il peut y avoir des erreurs, seulement si on envoie les données à chaque frame, le joueur ne verra pas l'erreur.
- requête HTTP : permet de communiquer avec un serveur HTTP. Avant d'éviter tout amalgame, elle ne permet pas d'afficher des sites web, mais de lire leur contenu. Elle ne permet pas non plus de naviguer à travers un DOM à la façon de javascript, si vous voulez le coder c'est tout à votre honneur. Elle permettrait de façon simple d'enregistrer des données par exemple, si vous voulez faire un système de trophée, que chaque joueur peut regarder les trophées des autres sur un site web, vous envoyez la requête http et le serveur le stockera dans la base de donnée.

La seule limite de tout ça est donc votre imagination (et votre capacité à scripter, pas forcément évident le réseau).

Ce qui n'a pas encore été fait :
- requête FTP : permettrait de lire les fichiers d'un serveur FTP, on pourrait l'utiliser pour une mise à jour automatique. Ceci dit, j'hésite à le faire, car il faut bien gérer ses permissions du serveur, au risque de tout perdre, et ce n'est pas forcément évident. Donc si vous voulez le voir implémenté, faites le moi savoir par MP, sinon je ne le ferait pas spécialement.

Ces 3 fonctionnalités sont indépendantes l'une des autres, vous pouvez n'en installer qu'une ou deux selon vos envies. Cependant, pour ces 3, il vous faudra les mêmes dll fournis ci dessous.

Crédits :
Voici la liste des crédits (à mettre dans votre fiche de crédits, là où sont cités les auteurs, oui il faut ça quelque part image" /> )
Développement de la bibliothèque C++ : SFML ( http://www.sfml-dev.org/ )
Intégration dans une DLL compatible avec RGSS : Otruch

Commun à toute fonctionnalité :
Pour tous, vous devez ajouter 3 dll à votre projet. Télécharger le .zip en cliquant ici.
Décompressez le, allez dans le dossier, et copiez les 3 dll (et non pas le dossier !), collez les dans la racine du projet. (la racine est l'élément principal, le dossier où il y a Game.exe).

La socket TCP
Installation
Créez un nouveau script avant le main et nommez le TcpSocket
Copiez y le code suivant :

Portion de code : Tout sélectionner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# TcpSocket : crée une socket TCP permettant de communiquer avec un serveur TCP
 
# Prérequis d'utilisation : il faut avoir dans le dossier racine de son projet
# les fichiers suivants : rgssnetwork.dll, sfml-network-2.dll, [url=https://www.rpg-maker.fr/divers/scripts/script501_rgssnetwork_sfml_system_2.zip]sfml-system-2.dll[/url]
 
# Crédits :
# Développement de la bibliothèque C++ : SFML ( [url=http://www.sfml-dev.org/]http://www.sfml-dev.org/[/url] )
# Intégration dans une DLL compatible avec RGSS : Otruch
class TcpSocket
   
    # Contantes de status : donne une information de l'état de l'action effectuée
    DONE = 0          # L'action a été effectuée avec succès
    NOT_READY = 1     # La socket n'est pas prête à envoyer/recevoir des données
    PARTIAL = 2       # La socket n'a envoyé qu'une portion de la donnée
    DISCONNECTED = 3  # La socket s'est déconnectée
    ERROR = 4         # Une erreur innatendue.
   
    # Importation des fonctions de la DLL, à ne pas utiliser manuellement.
    @@new = Win32API.new("rgssnetwork","RGSSNetworkTcpSocketAdd",["P"],"I")
    @@connect = Win32API.new("rgssnetwork","RGSSNetworkTcpSocketConnect",["I","P","I"],"I")
    @@connectTimeout =  Win32API.new("rgssnetwork","RGSSNetworkTcpSocketConnectTimeout",["I","P","I","I"],"I")
    @@setBlocking = Win32API.new("rgssnetwork","RGSSNetworkTcpSocketSetBlocking",["I","I"],"V")
    @@send = Win32API.new("rgssnetwork","RGSSNetworkTcpSocketSend",["I","P","I"],"I")
    @@receive = Win32API.new("rgssnetwork","RGSSNetworkTcpSocketReceive",["I","I"],"P")
    @@disconnect = Win32API.new("rgssnetwork","RGSSNetworkTcpSocketDisconnect",["I"],"V")
    @@delete = Win32API.new("rgssnetwork","RGSSNetworkTcpSocketDelete",["I"],"V")
     
  # Constructeur à l'appel de TcpSocket.new 
   
  # [replaceZero] : String : paramètre optionnel. Pour des problèmes de compatibilités,
  # le C++ remplace tout caractère '\0' par ce paramètre, ruby le reconvertit.
  # si au grand jamais votre serveur veut envoyer [[[AntislashZero]]], il sera transformé en \0,
  # si vous êtes dans ce rare cas, mettez en paramètre un code que vous n'utiliserez jamais
  # sinon, laissez tel quel.
  def initialize(replaceZero = "[[[AntislashZero]]]")
    @replaceZero = replaceZero
    @id = @@new.Call(replaceZero)
  end
   
  # Connecte la socket à l'addresse et au port demandés avec un timeout.
  # Si le timeout n'est pas spécifié, ça sera la valeur par défaut de l'OS.
   
  # host : String : addresse du serveur, peut être localhost, une adresse IP
  # ou un nom de domaine
  # port : entier positif : port du serveur à écouter.
  # [timeout] : entier positif : timeout de la connection donné en millisecondes.
   
  # return : Entier : donne l'état de la connection définit dans les constantes de status.
  def connect(host,port,timeout = nil)
    if timeout == nil then
      status = @@connect.Call(@id,host,port)
    else
      status = @@connectTimeout.Call(@id,host,port,timeout)
    end
    return status
  end
   
  # Définit si la socket est bloquante ou non bloquante.
  # Par défaut, la socket est bloquante.
   
  # blocking : boolean : true pour bloquante, false pour non bloquante.
  def setBlocking(blocking)
    arg = blocking ? 1 : 0
    @@setBlocking.Call(@id,arg)
  end
   
  # Envoie la donnée data à la socket connectée.
   
  # data : String : donnée à envoyer. Pour envoyer des paquets binaires, 
  # référez vous à Array.pack et String.unpack.
   
  #return : Entier : statut définit dans les constantes de status.
  def send(data)
    return @@send.Call(@id,data,data.length)
  end
   
  # Reçois les données en ayant pour maximum maxLength de caractères.
   
  # maxLength : le nombre de données maximum à recevoir.
   
  # return : String : la donnée reçue, si rien n'a été reçu, renvoie ""
  def receive(maxLength)
    data = @@receive.Call(@id,maxLength)
    return data.gsub(@replaceZero,"\0")
  end
   
  # Déconnecte la socket du serveur.
  def disconnect
    @@disconnect.Call(@id)
  end
   
  # Destructeur de la socket,
  # à utiliser impérativement lorsque vous n'en avez plus besoin ! Si vous ne le faites pas, cela génèrera des fuites de mémoires, certes invisibles pour l'utilisateur, mais se verrait bouffer sa RAM après 38 utilisations. Même après la fin du programme !
  # fait appel à la méthode disconnect.
  def destroy
    @@delete.Call(@id)
  end
end


Manuel d'utilisation :
Pour plusieurs actions, on vous renverra un status, décrivant l'état de l'action, les status sont définit dans les constantes suivantes :
TcpSocket::DONE : L'action a été effectuée avec succès
TcpSocket::NOT_READY : La socket n'est pas prête à envoyer/recevoir des données
TcpSocket::PARTIAL : La socket n'a envoyé qu'une portion de la donnée
TcpSocket::DISCONNECTED : La socket s'est déconnectée
TcpSocket::ERROR : Une erreur innatendue.

Pour créer une socket,on fait socket = TcpSocket.new
Pour des raisons de compatibilité avec le C++, il a fallu faire une chaine par défaut qui soit remplacée par '\0'. la chaine par défaut est "[[[AntislashZero]]]". Si par malheur votre serveur devrait envoyer cette chaine, ça poserait problème. Dans ce cas très rare, choisissez une autre chaine et créez la socket comme ceci : socket = TcpSocket.new("monAutreChaine")

Ensuite, après l'avoir créé, il faut la connecter au TcpServer, on le fait comme ceci :
socket.connect(addresse,port). Addresse étant un String valant "localhost", le nom de domaine ou l'addresse IP du serveur. Port étant un entier valant le port auquel communiquer (il faut que ça soit le même sur le serveur).
On peut aussi préciser un timeout en troisième paramètre, un entier en millisecondes, si le timeout n'est pas précisé il prendra la valeur par défaut de l'OS.
La valeur de retour est un status décrivant l'état de la connexion.
par exemple pour une seconde, localhost au port 800 :
status = socket.connect("localhost",800,1000)
if status == TcpSocket::DONE
#...

À partir de là, une connexion est crée, les socket peuvent alors communiquer.

Avant de passer à la communication, il faut faire un truc d'important :
Après avoir terminé d'utiliser la socket, il faut IMPERATIVEMENT faire appel à socket.destroy
Si vous ne le faites pas, cela génèrera des fuites de mémoires, certes invisibles pour l'utilisateur, mais se verrait bouffer sa RAM après 38 utilisations. Même après la fin du programme !


La methode destroy fait appel à la méthode disconnect.

Pour déconnecter une socket (la méthode destroy le fait mais on sait jamais, des fois que vous voulez la connecter ailleurs), c'est comme ça :
socket.disconnect

Pour envoyer une donnée, on fait appel à la méthode send, on envoie une chaine de caractère en argument. La valeur de retour est le status décrivant l'état de l'envoi.
Par exemple, j'envoie coucou au serveur :
status = socket.send("coucou")

Pour recevoir des données, on fait appel à la méthode receive, en passant le maximum de charactères qu'on veut recevoir. La valeur de retour est un String envoyé par le serveur, si la réception a échoué, il envoie "". Par exemple, si je ne veux pas recevoir au délà de 200 caractères, je fais :
data = socket.receive(200)

Si on veut envoyer et recevoir des paquets binaires tels qu'une série d'entiers, il est sage d'utiliser les méthodes Array.pack et String.unpack, cf la documentation.

Par défaut, les socket sont bloquantes, cela veut dire que le programme attend, "freeze", tant que l'on a pas reçu de données. On peut les rendre non bloquantes, ce qui ferait que si la donnée n'est pas envoyée, on reçoit "" mais on continue le programme.
Pour changer ce mode, on utilise la méthode setBlocking, en argument un booleen valant true si bloquant, false sinon
Pour mettre ma socket non bloquante, je fais socket.setBlocking(false)

La socket UDP
Installation :
Ajoutez un nouveau script, avant le Main, nommez le UdpSocket, et copiez y ceci :

Portion de code : Tout sélectionner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# Udp : crée une socket UDP permettant de communiquer avec d'autres sockets UDP
 
# Prérequis d'utilisation : il faut avoir dans le dossier racine de son projet
# les fichiers suivants : rgssnetwork.dll, sfml-network-2.dll, sfml-system-2.dll
 
# Crédits :
# Développement de la bibliothèque C++ : SFML ( [url=http://www.sfml-dev.org/]http://www.sfml-dev.org/[/url] )
# Intégration dans une DLL compatible avec RGSS : Otruch
 
class UdpSocket
   
  # Contantes de status : donne une information de l'état de l'action effectuée
  DONE = 0          # L'action a été effectuée avec succès
  NOT_READY = 1     # La socket n'est pas prête à envoyer/recevoir des données
  PARTIAL = 2       # La socket n'a envoyé qu'une portion de la donnée
  DISCONNECTED = 3  # La socket s'est déconnectée
  ERROR = 4         # Une erreur innatendue.
   
  # Importation des fonctions de la DLL, à ne pas utiliser manuellement.
  @@new = Win32API.new("rgssnetwork","RGSSNetworkUdpSocketAdd",["P"],"I")
  @@bind = Win32API.new("rgssnetwork","RGSSNetworkUdpSocketBind",["I","I"],"I")
  @@send = Win32API.new("rgssnetwork","RGSSNetworkUdpSocketSend",["I","P","I","P","I"],"I")
  @@receive = Win32API.new("rgssnetwork","RGSSNetworkUdpSocketReceive",["I","I"],"I")
  @@getLastData = Win32API.new("rgssnetwork","RGSSNetworkUdpSocketgetLastData",["I"],"P")
  @@getLastIp = Win32API.new("rgssnetwork","RGSSNetworkUdpSocketGetLastIp",["I"],"P")
  @@getLastPort = Win32API.new("rgssnetwork","RGSSNetworkUdpSocketGetLastPort",["I"],"I")
  @@setBlocking = Win32API.new("rgssnetwork","RGSSNetworkUdpSocketSetBlocking",["I","I"],"V")
  @@unbind = Win32API.new("rgssnetwork","RGSSNetworkUdpSocketUnbind",["I"],"V")
  @@delete = Win32API.new("rgssnetwork","RGSSNetworkUdpSocketDelete",["I"],"V")
   
  # Constructeur à l'appel de UdpSocket.new 
   
  # [replaceZero] : String : paramètre optionnel. Pour des problèmes de compatibilités,
  # le C++ remplace tout caractère '\0' par ce paramètre, ruby le reconvertit.
  # si au grand jamais votre serveur veut envoyer [[[AntislashZero]]], il sera transformé en \0,
  # si vous êtes dans ce rare cas, mettez en paramètre un code que vous n'utiliserez jamais
  # sinon, laissez tel quel.
  def initialize(replaceZero = "[[[AntislashZero]]]")
    @replaceZero = replaceZero
    @id = @@new.Call(replaceZero)
  end
   
  # Lie la socket à un port, une fois la socket liée, elle pourra recevoir des 
  # données via ce port.
   
  # port : Entier positif : le port auquel la socket sera liée.
   
  #return : Entier positif : return le status définit dans les constantes de status.
  def bind(port)
    return @@bind.Call(@id,port)
  end
   
  # Envoie les données data à l'adresse spécifiée, au port spécifié.
   
  # data : String : donnée à envoyer. Pour envoyer des paquets binaires, 
  # référez vous à Array.pack et String.unpack.
  # address : String : addresse à laquelle envoyer les données,
  # peut être localhost, un nom de domaine ou une addresse IP.
  # port : Entier positif : port auquel envoyer les données.
   
  #return : Entier positif : return le status définit dans les constantes de status.
  def send(data,address,port)
    return @@send.Call(@id,data,data.length,address,port)
  end
   
  # Reçois les données en ayant pour maximum maxLength de caractères.
   
  # maxLength : le nombre de données maximum à recevoir.
   
  # return : Array : [status,data,address,port] si le status est UdpSocket::DONE
  # ou Array : [status] si status est différent de UdpSocket::DONE
  # status : Entier positif : return le status définit dans les constantes de status.
  # data : String : donnée reçue
  # address : addresse de la socket qui a envoyé la donnée
  # port : port auquel est liée la socket qui a envoyé la donnée, 
  # utile pour envoyer des données, on utilisera ce port.
  def receive(maxLength)
    datas = []
    status = @@receive.Call(@id,maxLength)
    datas[0] = status
    if status == DONE then
      data = @@getLastData.Call(@id)
      datas[1] = data.gsub(@replaceZero,"\0")
      datas[2] = @@getLastIp.Call(@id)
      datas[3] = @@getLastPort.Call(@id)
    end
    return datas
  end
   
  # Définit si la socket est bloquante ou non bloquante.
  # Par défaut, la socket est bloquante.
   
  # blocking : boolean : true pour bloquante, false pour non bloquante.
  def setBlocking(blocking)
    arg = blocking ? 1 : 0
    @@setBlocking.Call(@id,arg)
  end
   
  # Délie la socket au port qu'elle écoutait, 
  # une fois appelée, elle ne pourra plus recevoir de données sur ce port.
  def unbind
    @@unbind.Call(@id)
  end
   
  # Destructeur de la socket,
  # à utiliser impérativement lorsque vous n'en avez plus besoin !
  # fait appel à la méthode unbind.
  def destroy
    @@delete.Call(@id)
  end
end



Manuel d'utilisation
Pour plusieurs actions, on vous renverra un status, décrivant l'état de l'action, les status sont définit dans les constantes suivantes :
UdpSocket::DONE : L'action a été effectuée avec succès
UdpSocket::NOT_READY : La socket n'est pas prête à envoyer/recevoir des données
UdpSocket::PARTIAL : La socket n'a envoyé qu'une portion de la donnée
UdpSocket::DISCONNECTED : La socket s'est déconnectée
UdpSocket::ERROR : Une erreur innatendue.

Pour créer une socket,on fait socket = UdpSocket.new
Pour des raisons de compatibilité avec le C++, il a fallu faire une chaine par défaut qui soit remplacée par '\0'. la chaine par défaut est "[[[AntislashZero]]]". Si par malheur votre serveur devrait envoyer cette chaine, ça poserait problème. Dans ce cas très rare, choisissez une autre chaine et créez la socket comme ceci : socket = UdpSocket.new("monAutreChaine")

Pour recevoir des données, il faut lier la socket à un port, cela se fait avec la méthode bind, avec pour argument le port, qui est un entier positif. La méthode renvoie le status qui décrit l'état de la connection.
exemple status = socket.bind(800)

Avant de passer à la communication, il faut faire un truc d'important :
Après avoir terminé d'utiliser la socket, il faut IMPERATIVEMENT faire appel à socket.destroy
Si vous ne le faites pas, cela génèrera des fuites de mémoires, certes invisibles pour l'utilisateur, mais se verrait bouffer sa RAM après 38 utilisations.Même après la fin du programme !

La methode destroy fait appel à la méthode unbind.

Pour délier la socket à un port, bien que la méthode destroy le fait, on peut toujours l'utiliser pour la relier à un autre port, on fait appel à la méthode unbind, comme ceci : socket.unbind

Pour envoyer des données à une autre socket udp, on fait appel à la méthode send, prenant en argument :
data : String qui sont les données sous forme de chaine de caractère
address : String : l'addresse de la socket, elle peut être "localhost", un nom de domaine, ou une addresse IP.
port : entier positif : le port à envoyer, celui qui est connecté à socket à laquelle communiquer. Elle peut être différente de celle où on est lié (ce qui est même conseillé car on risque de s'envoyer les données à soit même quand on travail en local.)
par exemple, je veux envoyer au localhost, la donnée "coucou" au port 800, je fais socket.send("coucou","localhost",800)

Pour recevoir des données, on fait appel à la méthode receive, prenant en argument maxLength, qui est le nombre de caractères maximum qu'on souhaite recevoir.
La socket retourne un Array comprenant :
- le status qui est l'état de la réception.
Si le status n'est pas égal à UdpSocket::DONE, ça s'arrête là,
--> donc renvoies [status]
si le status est égal à Udp::Socket::DONE, l'array comprend aussi :
- l'addresse IP de la socket qui envoie sous forme de chaine de caractère.
- le port qui est lié à la socket qui envoie, pour lui envoyer des données on utilisera donc ce port.
--> donc renvoies [status,address,port]

Si on veut envoyer et recevoir des paquets binaires tels qu'une série d'entiers, il est sage d'utiliser les méthodes Array.pack et String.unpack, cf la documentation.

Par défaut, les socket sont bloquantes, cela veut dire que le programme attend, "freeze", tant que l'on a pas reçu de données. On peut les rendre non bloquantes, ce qui ferait que si la donnée n'est pas envoyée, on reçoit "" mais on continue le programme.
Pour changer ce mode, on utilise la méthode setBlocking, en argument un booleen valant true si bloquant, false sinon
Pour mettre ma socket non bloquante, je fais socket.setBlocking(false)


La requête HTTP
Note : je n'ai testé que les méthodes GET et POST, et n'ai pas testé les header, parce que je n'y connais rien du tout, donc s'il y a un kwak, dites moi l'erreur et j'arrangerai ça.
Installation
Vous avez 2 scripts à ajouter.
Ajouter d'abord un premier script, avant le Main, nommez le HttpRequest et copiez y le code suivant :

Portion de code : Tout sélectionner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# HttpRequest : Classe représentant la requête HTTP.
 
# Prérequis d'utilisation : s'utilise avec HttpResponse
# voir les prérequis d'utilisation de HttpResponse
 
# Crédits :
# Développement de la bibliothèque C++ : SFML ( http://www.sfml-dev.org/ )
# Intégration dans une DLL compatible avec RGSS : Otruch
 
class HttpRequest
  # Constantes de méthodes de la requête.
  GET = 0
  POST = 1
  HEAD = 2
  PUT = 3
  DELETE = 4
   
  # Attributs publiques, utiliser marequete.attribut = valeur pour modifier
  # utiliser valeur = marequete.attribut pour lire la valeur.
  # marequete étant l'objet requête, attribut étant l'attribut sans le :
  attr_accessor :host     # String : nom de domaine auquel envoyer (exemple : "google.fr")
  attr_accessor :uri      # String : url sans le nom de domaine, (exemple : "/image.png" pour image.png se situant dans la racine.
  attr_accessor :method   # Entier : méthode de la requête définit dans les constantes de méthodes.
  attr_accessor :port     # Entier positif : port sur lequel faire la requête.
   
  # Attributs en lecture seule, utilisés pour HttpResponse.
  attr_reader :httpVersion
  attr_reader :fields
   
  # Constructeur à l'appel de HttpRequest.new
   
  # host : String : nom de domaine auquel envoyer
  # [uri] : String : optionnel : url sans le nom de domaine, par défaut "/"
  # [method] : Entier positif :  optionnel : méthode de la requête, 
  # utiliser les constantes de méthodes, par défaut GET
  # [port] : Entier positif : optionnel : port sur lequel envoyer, par défaut 80.
  def initialize(host,uri = "/",method = GET,port = 80)
    @host = host
    @uri = uri
    @method = method
    @port = port
    @httpVersion = [1,0]
    @fields = {}
    @posts = {}
  end
 
  # Change la version de http. Major représente le premier numéro, minor le second. (1,0) pour 1.0
  # par défaut 1.0
   
  # major : Entier positif : premier numéro de la version
  # minor : Entier positif : second numéro de la version
  def setHttpVersion(major,minor)
    @httpVersion = [major,minor]
  end
   
  # Ajoute un header à la requête.
   
  # name : String : nom du header
  # value : String : nom de la valeur
  def addHeader(name,value)
    @fields[name] = value
  end
 
  # Ajoute une variable post, n'est utile que dans une méthode POST
  # Précondition : name ne doit contenir que des chiffres, lettres non accentuées, "_" et "-"
   
  # name : String : nom de la variable
  # value : String : valeur de la variable
  def addVarPost(name,value)
    @posts[name] = value
  end
   
  # Encode les variables post, utilisé par getBody
  def urlEncode str
    return str.gsub(/([^a-z0-9])/i){|c|
      if c == ' ' then
        '+'
      else
        code  = c.unpack('C')[0].to_s(16)
        if code.length < 2 then
          code = '0' + code
        end
        '%' + code
      end
    }
  end
  # Utilisé par HttpResponse.
  def getBody()
    str = ""
    for var in @posts
      str += "&" + var[0].to_s + "=" + urlEncode(var[1])
    end
    return str.slice(1,str.length)
  end
end


Ajoutez le script suivant, juste après, toujours avant le Main, nommez le HttpResponse, et copiez y le code suivant :

Portion de code : Tout sélectionner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# HttpResponse : envoie une requête http en fonction de la requête,
# classe représentant la réponse http.
 
# Prérequis d'utilisation : il faut avoir dans le dossier racine de son projet
# les fichiers suivants : rgssnetwork.dll, sfml-network-2.dll, sfml-system-2.dll
# Il faut aussi importer la classe HttpRequest.
 
# Crédits :
# Développement de la bibliothèque C++ : SFML ( [url=http://www.sfml-dev.org/]http://www.sfml-dev.org/[/url] )
# Intégration dans une DLL compatible avec RGSS : Otruch
 
class HttpResponse
   
  # Constantes de status de la réponse, je ne vais pas toutes les énumérer,
  # référez vous à la doc de http.
   
  OK = 200
  CREATED = 201
  ACCEPTED = 202
  NO_CONTENT = 204
  RESET_CONTENT = 205
  PARTIAL_CONTENT = 206
  MULTIPLE_CHOICES = 300
  MOVED_PERMANENTLY = 301
  MOVED_TEMPORARILY = 302
  NOT_MODIFIED = 304
  BAD_REQUEST = 400
  UNAUTHORIZED = 401
  FORBIDEN = 403
  NOT_FOUND = 404
  RANGE_NOT_SATISFIABLE = 407
  INTERNAL_SERVER_ERROR = 500
  NOT_IMPLEMENTED = 501
  BAD_GATEWAY = 502
  SERVICE_NOT_AVAILABLE = 503
  GATEWAY_TIMEOUT = 504
  VERSION_NOT_SUPPORTED = 505
  INVALID_RESPONSE = 1000
  CONNECTION_FAILED = 1001
   
  # Importation des fonctions de la DLL, à ne pas utiliser manuellement.
  @@new = Win32API.new("rgssnetwork","RGSSNetworkHttpAdd",["P","P","I","I","P","I","I"],"I")
  @@addRequestHeader = Win32API.new("rgssnetwork","RGSSNetworkHttpAddRequestHeader",["I","P","P"],"V")
  @@sendRequest = Win32API.new("rgssnetwork","RGSSNetworkHttpSendRequest",["I"],"V")
  @@getHeader = Win32API.new("rgssnetwork","RGSSNetworkHttpGetResponseHeader",["I","P"],"P")
  @@getStatus = Win32API.new("rgssnetwork","RGSSNetworkHttpGetResponseStatus",["I"],"I")
  @@getMajorVersion = Win32API.new("rgssnetwork","RGSSNetworkHttpGetResponseMajorVersion",["I"],"I")
  @@getMinorVersion = Win32API.new("rgssnetwork","RGSSNetworkHttpGetResponseMinorVersion",["I"],"I")
  @@getBody = Win32API.new("rgssnetwork","RGSSNetworkHttpGetBody",["I"],"P")
  @@delete = Win32API.new("rgssnetwork","RGSSNetworkHttpDelete",["I"],"V")
   
  # Constructeur à l'appel de HttpResponse.new
  # Fait une requête HTTP en fonction de la requête, et stocket le résultat.
   
  # request : HttpRequest : requête à envoyer.
   
  def initialize(request)
    @id = @@new.Call(request.host,request.uri,request.method,request.port,request.getBody(),request.httpVersion[0],request.httpVersion[1])
    for header in request.fields
      @@addRequestHeader.Call(@id,header[0].to_s,header[1])
    end
    @@sendRequest.Call(@id)
  end
   
  # Donne la valeur du header donné en paramètre
  # retourne "" si le header n'est pas trouvé
   
  #name : String : nom du header
   
  # return : String : valeur du header.
  def getHeader(name)
    return @@getHeader.Call(@id,name)
  end
   
  # Donne le status de la requête
  # vous pouvez soit tester avec des entiers si vous êtes à l'aise
  # soit utiliser les constantes de status.
   
  # return : Entier positif : Valeur du status.
  def getStatus()
    return @@getStatus.Call(@id)
  end
   
  # Donne la version HTTP sous forme d'Array.
   
  # return : Array : [major,minor]
  # major : Entier positif : premier chiffre de la version (1 pour 1.0)
  # minor : Entier positif : second chiffre de la version (0 pour 1.0)
  def getHttpVersion()
    array = []
    array[0] = @@getMajorVersion.Call(@id)
    array[1] = @@getMinorVersion.Call(@id)
    return array
  end
   
  # Donne la version HTTP sous forme de String
   
  # return : String : version HTTP de la réponse.
  def getHttpVersionStr()
    return @@getMajorVersion.Call(@id).to_s + @@getMinorVersion.Call(@id).to_s
  end
   
  # Donne le corps de la requête, c'est ici que vous trouverez le html par exemple.
   
  # return : String : corps de la requête.
  def getBody()
    return @@getBody.Call(@id)
  end
   
  # Destructeur de la socket,
  # à utiliser impérativement lorsque vous n'en avez plus besoin !
  def destroy()
    @@delete.Call(@id)
  end
end



Manuel d'utilisation :
Une requête HTTP se fait en 2 parties : on crée la requête, on l'envoie au serveur, une réponse est créée, on la lit. Là j'ai fais les choses plus simplement, on crée la requête, on crée la réponse en y mettant la requête, l'envoie se fait automatiquement, on lit la réponse.
Etape 1, création de la requête via HTTPRequest :
Différentes constantes sont là pour le type de la méthode à envoyer :
HttpRequest::GET : demande la page par url
HttpRequest::POST : demande la page par url et y transmet des variables
HttpRequest::HEAD
HttpRequest::PUT
HttpRequest::DELETE
Si vous utilisez les méthodes HEAD, PUT et DELETE, c'est que vous les connaissez, moi perso je ne les connais pas, j'utilise que GET et POST.

Création de la requête :
On appelle le constructeur, on passe en argument :
host : String : le nom de domaine, peut être "localhost" (exemple "google.fr" )
uri : optionnel : String : le chemin par rapport à la racine, autrement dit ce qu'il y a après le nom de domaine dans l'url, par défaut "/"
method : optionnel : méthode de la requête, utilisez les constantes de méthode, par défaut GET
port : optionnel : entier positif : c'est le port où envoyer la requête, par défaut 80, c'est le port où écoute tous les serveurs web.
exemple : request = HttpRequest.new("localhost","/trophee.php",HttpRequest::POST)

Ces 4 attributs sont publics, on peut y accéder en écriture et en lecture, pour les changer et les lire, exemple :
request.host = "google.fr"
Cela permet par exemple, si on veut juste changer la méthode mais pas l'uri, de faire :
request = HttpRequest.new("localhost")
request.method = HttpRequest::POST

On peut changer la version de HTTP en appelant la méthode setHttpVersion et y indiquant le premier numéro et le second numéro, en entier,
pour la version "1.0" c'est request.setHttpVersion(1,0)
C'est à titre d'exemple, par défaut, la version est "1.0"

On peut ajouter/changer le header de la requête via la méthode addHeader. Le premier argument est le nom de l'header, le second est la valeur.
exemple :
request.addHeader("Content-Type", "application/x-www-form-urlencoded")

Pour une méthode post, on peut ajouter des variables via la méthode addVarPost, ayant le nom de la variable et sa valeur en argument.
Le nom de la variable ne doit contenir que des lettres non accentuées, chiffres, "-" et "_".

Il y a une méthode publique et des attributs en lecture seule, n'y touchez pas, elle sert d'utilitaire pour la classe HttpResponse.
Lire la réponse :
Beaucoup de constantes ont été créées pour le statut de la requête, en général on se sert des chiffres, mais il est toujours bien de pouvoir utiliser certaines constantes, à vous de voir.
Les constantes sont :
HttpResponse::OK = 200
HttpResponse::CREATED = 201
HttpResponse::ACCEPTED = 202
HttpResponse::NO_CONTENT = 204
HttpResponse::RESET_CONTENT = 205
HttpResponse::PARTIAL_CONTENT = 206
HttpResponse::MULTIPLE_CHOICES = 300
HttpResponse::MOVED_PERMANENTLY = 301
HttpResponse::MOVED_TEMPORARILY = 302
HttpResponse::NOT_MODIFIED = 304
HttpResponse::BAD_REQUEST = 400
HttpResponse::UNAUTHORIZED = 401
HttpResponse::FORBIDEN = 403
HttpResponse::NOT_FOUND = 404
HttpResponse::RANGE_NOT_SATISFIABLE = 407
HttpResponse::INTERNAL_SERVER_ERROR = 500
HttpResponse::NOT_IMPLEMENTED = 501
HttpResponse::BAD_GATEWAY = 502
HttpResponse::SERVICE_NOT_AVAILABLE = 503
HttpResponse::GATEWAY_TIMEOUT = 504
HttpResponse::VERSION_NOT_SUPPORTED = 505
HttpResponse::INVALID_RESPONSE = 1000
HttpResponse::CONNECTION_FAILED = 1001

On initialise la réponse grâce à la requête, la requête est directement envoyée.
response = HttpResponse.new(request)

Attention, il est IMPERATIF d'utiliser la méthode destroy quand on n'a plus besoin de la reponse.
response.destroy

On lit le statut de la requête via la méthode getStatus
status = response.getStatus

Pour avoir la valeur d'un header, c'est la méthode getHeader avec pour paramètre, le nom du header
exemple : contentType = response.getHeader("Content-Type")

On peut avoir la version http de la réponse de deux manières :
dans un array via la méthode getHttpVersion , le premier élément est le premier chiffre, le second est le deuxième chiffre (pour "1.0" on a [1,0] )
version = response.getHttpVersion
if version[0] == 1 then
#...
ou dans un String via la méthode getHttpVersionStr
version = response.getHttpVersionStr

Et enfin, ce que vous attendez tous, le contenu de la réponse ! On peut y voir par exemple le html, ou le contenu d'une image, ou un simple "coucou" fait avec un echo en php. On y accède via la méthode getBody .
contenu = response.getBody


Mis à jour le 22 mai 2021.






mtarzaim - posté le 23/05/2015 à 21:14:00 (2926 messages postés)

❤ 0

Anaxagoras -500 BC

image

featuring trouze milles posts de kikoo qui veulent refaire GTA Online avec RPG Maker, mais sans le moindre background en programmation derrière.

Otruch a ouvert la boite de Pandore. Il sera maudit par les modos pour ça.

Beau boulot quand même. Pouvoir marier du sfml et du RGSS ouvre de sacrées possibilités.

Projets terminés : DIX Life Precious - TheFrogStudio.Net


Otruch - posté le 24/05/2015 à 04:33:08 (5 messages postés)

❤ 0

Merci :)

J'ai précisé dans mon post qu'il faut savoir scripter pour ça, et je n'ai pas encore eu de post de kikoo :p (ça va pas tarder?)

Mais il sera utile, peut être pas ici, ou peut être aussi ici.

Pour SFML : tout ce qui est graphisme, on pourra pas y toucher sauf si on crée une nouvelle fenêtre, ce qui enlèverait tout le graphisme et les entrées claviers de RGSS, dans ce cas autant ne pas utiliser RGSS du tout.
Parcontre il y a le module audio qui peut être intéressant, avec la spatialisation du son :) (Mais bon je vous laisse faire je suis occupé à autre chose :p)


verehn - posté le 25/05/2015 à 16:47:19 (9058 messages postés) - honor

❤ 0

Vhehrhehn

Comme le script ne s'intitule pas "Faire un MMORPG Narouteau !!!!!!!" ça devrait bien se passer niveau kikoo. :F

(Et là il se souvient qu'il existe réellement un MMO Naruto dans la commu :-/)

Eldrao ~ PakuPaku ~ Winged Light ~ Ruin ~ Ma galerie ~ LTDAD ~ Don de graphismes plateforme 2D


livekontesk - posté le 20/08/2015 à 20:11:20 (6 messages postés)

❤ 0

Bonjour bonjour,

Je suis très intéressé par ton script mais je n'arrive pas à télécharger les DLLs.
Peut tu faire parvenir un autre lien ?

Merci d'avance ! :sourire2


Otruch - posté le 16/02/2017 à 20:53:33 (5 messages postés)

❤ 0

Désolé pour la réponse tardive, lien mort. (Je vie dans une grotte, le vieux sage ne poste pas beaucoup, sauf quand il a besoin de provisions pour hiberner, il sort de sa grotte).

nouveau lien ici : http://www.filedropper.com/rgss-network

Si un modo pourrait updater le lien sur le poste, ça serait super gentil.


Gari - posté le 23/10/2020 à 16:51:27 (5901 messages postés) - honor

❤ 0

J'essaye de retrouver les dll manuellement, mais c'est pas gagné.

Les fichiers suivants sont indispensables au fonctionnement de l'ensemble :
- rgssnetwork.dll : je crois qu'il s'agit de la dll créée par Otruch pour adapter le SFML.Net à RPG Maker
- sfml-network-2.dll : ça ressemble à un fichier source du site ci-dessous, mais je n'ai pas trouvé le terme exact. Je suppose qu'il ne s'agit pas de csfml-network-2.dll...
- sfml-system-2.dll : retrouvé assez facilement. Lien recommandé : Le site officiel

J'ai envoyé un mail au scripteur, mais si quelqu'un a le projet sous la main et peut envoyer les dll, ce serait bien.

Suite à de nombreux abus, le post en invités a été désactivé. Veuillez vous inscrire si vous souhaitez participer à la conversation.

Haut de page

Merci de ne pas reproduire le contenu de ce site sans autorisation.
Contacter l'équipe - Mentions légales

Plan du site

Communauté: Accueil | Forum | Chat | Commentaires | News | Flash-news | Screen de la semaine | Sorties | Tests | Gaming-Live | Interviews | Galerie | OST | Blogs | Recherche
Apprendre: Visite guidée | RPG Maker 95 | RPG Maker 2003 | RPG Maker XP | RPG Maker VX | RPG Maker MV | Tutoriels | Guides | Making-of
Télécharger: Programmes | Scripts/Plugins | Ressources graphiques / sonores | Packs de ressources | Midis | Eléments séparés | Sprites
Jeux: Au hasard | Notre sélection | Sélection des membres | Tous les jeux | Jeux complets | Le cimetière | RPG Maker 95 | RPG Maker 2000 | RPG Maker 2003 | RPG Maker XP | RPG Maker VX | RPG Maker VX Ace | RPG Maker MV | Autres | Proposer
Ressources RPG Maker 2000/2003: Chipsets | Charsets | Panoramas | Backdrops | Facesets | Battle anims | Battle charsets | Monstres | Systems | Templates
Ressources RPG Maker XP: Tilesets | Autotiles | Characters | Battlers | Window skins | Icônes | Transitions | Fogs | Templates
Ressources RPG Maker VX: Tilesets | Charsets | Facesets | Systèmes
Ressources RPG Maker MV: Tilesets | Characters | Faces | Systèmes | Title | Battlebacks | Animations | SV/Ennemis
Archives: Palmarès | L'Annuaire | Livre d'or | Le Wiki | Divers