Pokémon Script Project Index du Forum

S’enregistrer | Rechercher | Connexion
 Information des admins 
Si vous désirez parler de PSP ou obtenir du soutient là dessus, merci d'aller faire un tour sur https://pokemonworkshop.com/forum/index.php Imbécile heureux

Echanges en temps réel v2.1
Aller à la page: 1, 2, 3, 4, 5  >
 
Poster un nouveau sujet   Répondre au sujet    Pokémon Script Project Index du Forum -> Game Making -> Ressources techniques -> Scripts
Sujet précédent :: Sujet suivant   
Auteur Message
Sphinx
Scribe
Scribe


Inscrit le: 07 Jan 2008
Messages: 9 736
Localisation: Quelque part, dans le monde... Ou peut être sur une autre planète...
ID Steam: FaQuinator

MessagePosté le: Mer 24 Aoû - 17:25 (2011)    Sujet du message: Echanges en temps réel v2.1

Echanges en temps réel v2.1


    T'as déjà posté un topic à ce sujet... Les modos vont te coller un avertissement !

Ou pas Yeux motorisés En effet, voici la version 2.1 du système d'échanges en temps réel ! Et cette fois, plus aucun code n'est à échanger ^^

    I) Principe général

Une vidéo vaudra toujours plus que 1000 mots, alors voici :


    II) Installation :

Cette partie est la plus complexe de ce tutorial. Je vais donc faire au mieux pour ne pas m'attarder sur les détails - pour ceux que ca intéresse, j'y consacrerai la prochaine partie -, mais je vous conseille également de relire autant de fois que nécessaire.
L'installation se décompose en deux sous parties :
      A) Installation côté serveur :

    Derrière ce titre effrayant se cache quelque chose de très simple, finalement. Le seul prérequis indispensable, c'est un hébergement qui permette d'exécuter des pages PHP (il en existe énormément de gratuits sur internet, inutile de vous ruiner pour ce tutorial). Ceci dit, je n'ai testé qu'avec un serveur Free (maintenant ils n'ouvrent plus d'espace persos qu'à leurs abonnés) dont je me suis servi pour mettre au point ce système. Mais tout semble indiquer que ca marchera très bien également sur n'importe quel autre hébergeur, dès l'instant qu'il n'ajoute aucune publicités.
    Pour trouver un hébergeur gratuit qui vous permette d'ouvrir un espace personnel, je peux vous proposer cette liste, mais une recherche sur Google (avec les mots clés suivants, par exemple : "liste d'hébergeurs gratuits sans publicité") vous permettra de trouver d'autres résultats intéressants.

    Pour faire simple, créez simplement un dossier (que vous pouvez appeler echanges et placé à la racine de votre serveur par exemple) puis placez y ce fichier :

    (pensez à le dézipper avant de le placer sur votre serveur, bien sur ^^)

    Retenez l'endroit où est placé ce fichier, vous en aurez besoin tout à l'heure.

      B) Installation dans votre projet :

    Cette fois le titre est simple à comprendre, et ne fait pas peur. Toutefois, vous verrez qu'il y a plusieurs scripts à installer, ce sera donc un peu plus long que pour le point précédent.
    Tout d'abord, vous devrez installer les scripts suivants :


    Ensuite, vous devez copier les scripts suivants au dessus de Main dans votre projet :
    Code:
    #=======================================================================
    # Socket écrit par Yuri et utilisé par Sphinx pour le système d'échanges en temps réel
    # réalisé avec la participation de Disscat, Samyh et Yuri
    # Contient de nouveaux modules et classes ainsi que des modules et classes redéfinis
    #   ¤ Win32
    #   ¤ Numeric
    #   ¤ String
    #   ¤ Winsock
    #   ¤ Socket
    #   ¤ TCPSocket
    #   ¤ SocketError
    #
    # Versions :
    #   ¤ version 1.0 : 13 Août 2011
    #   ¤ version 2.0 : 24 Août 2011
    #
    # Credits demandes :
    #   ¤ Disscat (animation d'échange & d'attente et interface d'informations du pokémon recu)
    #   ¤ Samyh (fond de la scène d'échange)
    #   ¤ Sphinx (élaboration du système d'échange)
    #   ¤ Yuri (classes Socket et Web_File indispensables à ce système)
    #
    # Remerciemments égalemment aux autres membres qui ont bien voulu tester en
    # avant première ce système :
    #   ¤ Angi-Mk
    #   ¤ Emeraude
    #   ¤ Palbolsky
    #   ¤ Spiky
    #=======================================================================
    module Win32
      Rtl_Move_MEM=Win32API.new("kernel32", "RtlMoveMemory", "ppl", "")
      def copymem(len)
        buf = "\0" * len
        Rtl_Move_MEM.call(buf, self, len)
        buf
      end
    end
    class Numeric
      include Win32
    end
    class String
      include Win32
    end

    module Winsock
      DLL = "ws2_32"
      A_ACCEPT=Win32API.new(DLL, "accept", "ppl", "l")
      A_BLIND=Win32API.new(DLL, "bind", "ppl", "l")
      A_CLOSE_S=Win32API.new(DLL, "closesocket", "p", "l")
      A_CONNECT=Win32API.new(DLL, "connect", "ppl", "l")
      A_GHBADD=Win32API.new(DLL, "gethostbyaddr", "pll", "l")
      A_GHBNAME=Win32API.new(DLL, "gethostbyname", "p", "l")
      A_GHNAME=Win32API.new(DLL, "gethostname", "pl", "")
      A_GSBNAME=Win32API.new(DLL, "getservbyname", "pp", "p")
      A_HTONL=Win32API.new(DLL, "htonl", "l", "l")
      A_HTONS=Win32API.new(DLL, "htons", "l", "l")
      A_INET_ADD=Win32API.new(DLL, "inet_addr", "p", "l")
      A_INET_NTOA=Win32API.new(DLL, "inet_ntoa", "l", "p")
      A_LISTEN=Win32API.new(DLL, "listen", "pl", "l")
      A_RECV=Win32API.new(DLL, "recv", "ppll", "l")
      A_SELECT=Win32API.new(DLL, "select", "lpppp", "l")
      A_SEND=Win32API.new(DLL, "send", "ppll", "l")
      A_SSOPT=Win32API.new(DLL, "setsockopt", "pllpl", "l")
      A_SHUT_DOWN=Win32API.new(DLL, "shutdown", "pl", "l")
      A_SOCKET=Win32API.new(DLL, "socket", "lll", "l")
      A_LAST_ERR=Win32API.new(DLL, "WSAGetLastError", "", "l")
      def self.accept(*args)
        A_ACCEPT.call(*args)
      end
      def self.bind(*args)
        A_BLIND.call(*args)
      end
      def self.closesocket(*args)
        A_CLOSE_S.call(*args)
      end   
      def self.connect(*args)
        A_CONNECT.call(*args)
      end       
      def self.gethostbyaddr(*args)
        A_GHBADD.call(*args)
      end
      def self.gethostbyname(*args)
        A_GHBNAME.call(*args)
      end
      def self.gethostname(*args)
        A_GHNAME.call(*args)
      end
      def self.getservbyname(*args)
        A_GSBNAME.call(*args)
      end
      def self.htonl(*args)
        A_HTONL.call(*args)
      end
      def self.htons(*args)
        A_HTONS.call(*args)
      end
      def self.inet_addr(*args)
        A_INET_ADD.call(*args)
      end
      def self.inet_ntoa(*args)
        A_INET_NTOA.call(*args)
      end   
      def self.listen(*args)
        A_LISTEN.call(*args)
      end
      def self.recv(*args)
        A_RECV.call(*args)
      end
      def self.select(*args)
        A_SELECT.call(*args)
      end
      def self.send(*args)
        A_SEND.call(*args)
      end
      def self.setsockopt(*args)
        A_SSOPT.call(*args)
      end   
      def self.shutdown(*args)
        A_SHUT_DOWN.call(*args)
      end
      def self.socket(*args)
        A_SOCKET.call(*args)   
      end
      def self.WSAGetLastError(*args)
        A_LAST_ERR.call(*args)
      end
    end
    class Socket
      API_WRITE=Win32API.new("msvcrt", "_write", "lpl", "l")
      AF_UNSPEC = 0   
      AF_UNIX = 1
      AF_INET = 2
      AF_IPX = 6
      AF_APPLETALK = 16
      PF_UNSPEC = 0   
      PF_UNIX = 1
      PF_INET = 2
      PF_IPX = 6
      PF_APPLETALK = 16
      SOCK_STREAM = 1
      SOCK_DGRAM = 2
      SOCK_RAW = 3
      SOCK_RDM = 4
      SOCK_SEQPACKET = 5
      IPPROTO_IP = 0
      IPPROTO_ICMP = 1
      IPPROTO_IGMP = 2
      IPPROTO_GGP = 3
      IPPROTO_TCP = 6
      IPPROTO_PUP = 12
      IPPROTO_UDP = 17
      IPPROTO_IDP = 22
      IPPROTO_ND = 77
      IPPROTO_RAW = 255
      IPPROTO_MAX = 256
      SOL_SOCKET = 65535
      SO_DEBUG = 1
      SO_REUSEADDR = 4
      SO_KEEPALIVE = 8
      SO_DONTROUTE = 16
      SO_BROADCAST = 32
      SO_LINGER = 128
      SO_OOBINLINE = 256
      SO_RCVLOWAT = 4100
      SO_SNDTIMEO = 4101
      SO_RCVTIMEO = 4102
      SO_ERROR = 4103
      SO_TYPE = 4104
      SO_SNDBUF = 4097
      SO_RCVBUF = 4098
      SO_SNDLOWAT = 4099
      TCP_NODELAY = 1
      MSG_OOB = 1
      MSG_PEEK = 2
      MSG_DONTROUTE = 4
      IP_OPTIONS = 1
      IP_DEFAULT_MULTICAST_LOOP = 1
      IP_DEFAULT_MULTICAST_TTL   = 1
      IP_MULTICAST_IF = 2
      IP_MULTICAST_TTL = 3
      IP_MULTICAST_LOOP = 4
      IP_ADD_MEMBERSHIP = 5
      IP_DROP_MEMBERSHIP = 6
      IP_TTL = 7
      IP_TOS = 8
      IP_MAX_MEMBERSHIPS = 20
      EAI_ADDRFAMILY = 1
      EAI_AGAIN = 2
      EAI_BADFLAGS = 3
      EAI_FAIL = 4
      EAI_FAMILY = 5
      EAI_MEMORY = 6
      EAI_NODATA = 7
      EAI_NONAME = 8
      EAI_SERVICE = 9
      EAI_SOCKTYPE = 10
      EAI_SYSTEM = 11
      EAI_BADHINTS = 12
      EAI_PROTOCOL = 13
      EAI_MAX = 14
      AI_PASSIVE = 1
      AI_CANONNAME = 2
      AI_NUMERICHOST = 4
      AI_MASK = 7
      AI_ALL = 256
      AI_V4MAPPED_CFG = 512
      AI_ADDRCONFIG = 1024
      AI_DEFAULT = 1536
      AI_V4MAPPED = 2048   
      attr_accessor :recv_size
      def self.getaddress(host)
        gethostbyname(host)[3].unpack("C4").join(".")
      end 
      def self.getservice(serv)
        case serv
        when Numeric
          return serv
        when String
          return getservbyname(serv)
        else
          raise "Please us an interger or string for services."
        end
      end
      def self.gethostbyname(name)
        raise SocketError::ENOASSOCHOST if (ptr = Winsock.gethostbyname(name)) == 0
        host = ptr.copymem(16).unpack("iissi")
        [host[0].copymem(64).split("\0")[0], [], host[2], host[4].copymem(4).unpack("l")[0].copymem(4)]
      end
      def self.gethostname
        buf = "\0" * 256
        Winsock.gethostname(buf, 256)
        buf.strip
      end
      def self.getservbyname(name)
        case name
        when /echo/i
          return 7
        when /daytime/i
          return 13
        when /ftp/i
          return 21
        when /telnet/i
          return 23
        when /smtp/i
          return 25
        when /time/i
          return 37
        when /http/i
          return 80
        when /pop/i
          return 110
        else
          raise "Service not recognized."
        end
      end 
      def self.sockaddr_in(port, host)
        begin
          [AF_INET, getservice(port)].pack("sn") + gethostbyname(host)[3] + [].pack("x8")
        rescue
          nil
        end
      end
      def self.open(*args)
        socket = new(*args)
        if block_given?
          begin
              yield socket
          ensure
              socket.close
          end
        end
        nil
      end 
      def initialize(domain, type, protocol)
        SocketError.check if (@fd = Winsock.socket(domain, type, protocol)) == -1
        @fd
      end
      def accept(flags = 0)
        buf = "\0" * 16
        SocketError.check if Winsock.accept(@fd, buf, flags) == -1
        buf
      end
      def bind(sockaddr)
        SocketError.check if (ret = Winsock.bind(@fd, sockaddr, sockaddr.size)) == -1
        ret
      end   
      def close
        SocketError.check if (ret = Winsock.closesocket(@fd)) == -1
        ret
      end 
      def connect(sockaddr)
        ret = Winsock.connect(@fd, sockaddr, sockaddr.size)
        SocketError.check if ret == -1
        ret
      end
      def listen(backlog)
        SocketError.check if (ret = Winsock.listen(@fd, backlog)) == -1
        ret
      end   
      def select(timeout)
        SocketError.check if (ret = Winsock.select(1, [1, @fd].pack("ll"), 0, 0, [timeout, timeout * 1000000].pack("ll"))) == -1
        ret
      end
      def ready?
        not select(0) == 0
      end   
      def read(len)
        buf = "\0" * len
        Win32API.new("msvcrt", "_read", "lpl", "l").call(@fd, buf, len)
        buf
      end 
      def recv(len, flags = 0)
        buf = "\0" * len
        SocketError.check if (@recv_size=Winsock.recv(@fd, buf, buf.size, flags)) == -1
        buf
      end
      def send(data, flags = 0)
        SocketError.check if (ret = Winsock.send(@fd, data, data.size, flags)) == -1
        ret
      end
      def gets
        # Create buffer
        buffer = ""
        # Loop Until "end of line"
        cm=false
        while ((char = recv(1)) != "\n" and not cm)
          if char == "\r"
            cm=true
          else
            buffer += char
          end
        end
        # Return recieved data
        return buffer
      end
      def write(data)
        API_WRITE.call(@fd, data, 1)
      end
    end
    class TCPSocket < Socket 
      def self.open(*args)
        socket = new(*args)
        if block_given?
          begin
            yield socket
          ensure
            socket.close
          end
        end
        nil
      end 
      def initialize(host, port)
        super(AF_INET, SOCK_STREAM, IPPROTO_TCP)
        connect(Socket.sockaddr_in(port, host))
      end
    end
    class SocketError < StandardError
      ENOASSOCHOST = "getaddrinfo: no address associated with hostname."
      def self.check
        errno = Winsock.WSAGetLastError
        errno = Errno.constants.detect { |c| Errno.const_get(c).new.errno == errno }
        if errno != nil
          $socket_error=Errno.const_get(errno)
        end
      end
    end

    Code:
    #=======================================================================
    # Web_File écrit par Yuri et utilisé par Sphinx pour le système d'échanges en temps réel
    # réalisé avec la participation de Disscat, Samyh et Yuri
    # Contient la nouvelle classe Web_File
    #
    # Versions :
    #   ¤ version 1.0 : 13 Août 2011
    #   ¤ version 2.0 : 24 Août 2011
    #
    # Credits demandes :
    #   ¤ Disscat (animation d'échange & d'attente et interface d'informations du pokémon recu)
    #   ¤ Samyh (fond de la scène d'échange)
    #   ¤ Sphinx (élaboration du système d'échange)
    #   ¤ Yuri (classes Socket et Web_File indispensables à ce système)
    #
    # Remerciemments égalemment aux autres membres qui ont bien voulu tester en
    # avant première ce système :
    #   ¤ Angi-Mk
    #   ¤ Emeraude
    #   ¤ Palbolsky
    #   ¤ Spiky
    #=======================================================================
    class Web_File
      attr_accessor :url, :host, :data, :variables
      #=================#
      #§Initialisation #
      #-----------------+--------------------------------------------------------------------------------------------------------#
      #=> Web_File.new("url-complète-sans-le-http://","?get=salut&msg=mange des cannes","post=salut&msg=mange des cannes") #
      #==========================================================================================================================#
      def initialize(url,variables={})
        slash = url.index("/")
        fin = url.length
        @host = url[0...slash]
        @url = url[slash...fin]
        @data = ""
        @variables = variables
        @variables["tradeGroup"] = "#{POKEMON_S::TRADEGROUP}"
        @variables["marshalGroup"] = "#{Marshal::MARSHALGROUP}"
      end
      #=============================================================#
      #§Lecture des données en fonction de @post ou @get           #
      #-------------------------------------------------------------#
      #=> mettre read(false) pour lire en mode get                  #
      #=> mettre false dans le deuxième arg pour ne pas utiliser GC #
      #=============================================================#
      def read(post=true,gc=true)
        socket=TCPSocket.new(@host,80)
        return "" unless socket.listen(0)
        unless post
          socket.send("GET #{@url}#{make_var(true)} HTTP/1.1\r\nHost: #{@host}\r\nConnection: Close\r\n\r\n")
        else
          post=make_var
          socket.send("POST #{@url} HTTP/1.1\r\nHost: #{@host}\r\nConnection: Close\r\nContent-type: application/x-www-form-urlencoded; charset=utf-8\r\nContent-Length: #{post.size}\r\n\r\n#{post}")
        end
        if @data != ""
          @data=nil
          GC.start#vidage du précedent
          @data=""
        end
        predata=""
        loop do
          break if socket.gets==""
        end
        @data=read_recv_data(socket,predata,gc)
      end
      #===================================================#
      #§Lecture de ce qui n'est pas censé être le header #
      #---------------------------------------------------#
      #  Methode séparé de read en cas d'édition          #
      #===================================================#
      def read_recv_data(socket,data,gc)
        pos=0
        loop do
          pos+=1
          d=socket.recv(5120)
          break if socket.recv_size == 0 or socket.recv_size == -1
          data+=d[0...socket.recv_size]
          if pos == 5120
            pos=0
            Graphics.update
          end
        end
        d=nil
        socket.close
        socket=nil
        GC.start if gc
        data
      end
      #=======================================#
      #§Encodage des données pour le serveur #
      #---------------------------------------#
      #  L'encodage est peut être incomplet   #
      #=======================================#
      def get_to_httpget(var)
        var.gsub!("%","%25")
        var.gsub!("$","%24")
        var.gsub!("+","%2B")
        var.gsub!(",","%2C")
        var.gsub!("\"","%22")
        var.gsub!("<","%3C")
        var.gsub!(">","%3E")
        var.gsub!("{","%7B")
        var.gsub!("}","%7D")
        var.gsub!("|","%7C")
        var.gsub!("\\","%5C")
        var.gsub!("^","%5E")
        var.gsub!("~","%7E")
        var.gsub!("[","%5B")
        var.gsub!("]","%5D")
        var.gsub!("`","%60")
        var.gsub!(" ","%20")
        return var
      end
      def post_to_httppost(var)
        var.gsub!("%","%25")
        var.gsub!("+","%2B")
        var.gsub!(" ", "+")
        var.gsub!("!", "%21")
        var.gsub!("\"", "%22")
        var.gsub!("#", "%23")
        var.gsub!("$", "%24")
        var.gsub!("&", "%26")
        var.gsub!("'", "%27")
        var.gsub!("(", "%28")
        var.gsub!(")", "%29")
        var.gsub!("*", "%2A")
        var.gsub!(",", "%2C")
        var.gsub!("/", "%2F")
        var.gsub!(":", "%3A")
        var.gsub!(";", "%3B")
        var.gsub!("<", "%3C")
        var.gsub!("=", "%3D")
        var.gsub!(">", "%3E")
        var.gsub!("?", "%3F")
        var.gsub!("@", "%40")
        var.gsub!("[", "%5B")
        var.gsub!("\\", "%5C")
        var.gsub!("]", "%5D")
        var.gsub!("^", "%5E")
        var.gsub!("`", "%60")
        var.gsub!("{", "%7B")
        var.gsub!("|", "%7C")
        var.gsub!("}", "%7D")
        var.gsub!("~", "%7E")
        var.gsub!("€", "%80")
        var.gsub!("", "%81")
        var.gsub!("‚", "%82")
        var.gsub!("„", "%84")
        var.gsub!("…", "%85")
        var.gsub!("†", "%86")
        var.gsub!("‡", "%87")
        var.gsub!("ˆ", "%88")
        var.gsub!("‰", "%89")
        var.gsub!("Š", "%8A")
        var.gsub!("‹", "%8B")
        var.gsub!("Œ", "%8C")
        var.gsub!("Ž", "%8E")
        var.gsub!("‘", "%91")
        var.gsub!("’", "%92")
        var.gsub!("“", "%93")
        var.gsub!("”", "%94")
        var.gsub!("•", "%95")
        var.gsub!("–", "%96")
        var.gsub!("—", "%97")
        var.gsub!("˜", "%98")
        var.gsub!("™", "%99")
        var.gsub!("š", "%9A")
        var.gsub!("›", "%9B")
        var.gsub!("œ", "%9C")
        var.gsub!("ž", "%9E")
        var.gsub!("Ÿ", "%9F")
        var.gsub!("¡", "%A1")
        var.gsub!("¢", "%A2")
        var.gsub!("£", "%A3")
        var.gsub!("¤", "%A4")
        var.gsub!("¥", "%A5")
        var.gsub!("¦", "%A6")
        var.gsub!("§", "%A7")
        var.gsub!("¨", "%A8")
        var.gsub!("©", "%A9")
        var.gsub!("ª", "%AA")
        var.gsub!("«", "%AB")
        var.gsub!("¬", "%AC")
        var.gsub!("­", "%AD")
        var.gsub!("®", "%AE")
        var.gsub!("¯", "%AF")
        var.gsub!("°", "%B0")
        var.gsub!("±", "%B1")
        var.gsub!("²", "%B2")
        var.gsub!("³", "%B3")
        var.gsub!("´", "%B4")
        var.gsub!("µ", "%B5")
        var.gsub!("¶", "%B6")
        var.gsub!("·", "%B7")
        var.gsub!("¸", "%B8")
        var.gsub!("¹", "%B9")
        var.gsub!("º", "%BA")
        var.gsub!("»", "%BB")
        var.gsub!("¼", "%BC")
        var.gsub!("½", "%BD")
        var.gsub!("¾", "%BE")
        var.gsub!("¿", "%BF")
        var.gsub!("À", "%C0")
        var.gsub!("Á", "%C1")
        var.gsub!("Â", "%C2")
        var.gsub!("Ã", "%C3")
        var.gsub!("Ä", "%C4")
        var.gsub!("Å", "%C5")
        var.gsub!("Æ", "%C6")
        var.gsub!("Ç", "%C7")
        var.gsub!("È", "%C8")
        var.gsub!("É", "%C9")
        var.gsub!("Ê", "%CA")
        var.gsub!("Ë", "%CB")
        var.gsub!("Ì", "%CC")
        var.gsub!("Í", "%CD")
        var.gsub!("Î", "%CE")
        var.gsub!("Ï", "%CF")
        var.gsub!("Ð", "%D0")
        var.gsub!("Ñ", "%D1")
        var.gsub!("Ò", "%D2")
        var.gsub!("Ó", "%D3")
        var.gsub!("Ô", "%D4")
        var.gsub!("Õ", "%D5")
        var.gsub!("Ö", "%D6")
        var.gsub!("×", "%D7")
        var.gsub!("Ø", "%D8")
        var.gsub!("Ù", "%D9")
        var.gsub!("Ú", "%DA")
        var.gsub!("Û", "%DB")
        var.gsub!("Ü", "%DC")
        var.gsub!("Ý", "%DD")
        var.gsub!("Þ", "%DE")
        var.gsub!("ß", "%DF")
        var.gsub!("à", "%E0")
        var.gsub!("á", "%E1")
        var.gsub!("â", "%E2")
        var.gsub!("ã", "%E3")
        var.gsub!("ä", "%E4")
        var.gsub!("å", "%E5")
        var.gsub!("æ", "%E6")
        var.gsub!("ç", "%E7")
        var.gsub!("è", "%E8")
        var.gsub!("ê", "%EA")
        var.gsub!("ë", "%EB")
        var.gsub!("ì", "%EC")
        var.gsub!("í", "%ED")
        var.gsub!("î", "%EE")
        var.gsub!("ï", "%EF")
        var.gsub!("ð", "%F0")
        var.gsub!("ñ", "%F1")
        var.gsub!("ò", "%F2")
        var.gsub!("ó", "%F3")
        var.gsub!("ô", "%F4")
        var.gsub!("õ", "%F5")
        var.gsub!("ö", "%F6")
        var.gsub!("÷", "%F7")
        var.gsub!("ø", "%F8")
        var.gsub!("ù", "%F9")
        var.gsub!("ú", "%FA")
        var.gsub!("û", "%FB")
        var.gsub!("ü", "%FC")
        var.gsub!("ý", "%FD")
        var.gsub!("þ", "%FE")
        return var
      end
      #===============================#
      #§Ajout / edition de variables #
      #===============================#
      def edit_variables(name,data,gc=true)
        if @variables[name]
          @variables[name]=nil
          GC.start if gc
          @variables[name]= (data.class==String ? data : data.to_s)
        else
          @variables[name]= (data.class==String ? data : data.to_s)
        end
      end
      #=================================================#
      #§création de la requete contenant les variables #
      #=================================================#
      def make_var(get=false)
        if get
          data="?"
          first=true
          for i in @variables
            unless first
              data+="&"
            else
              first=false
            end
            data+="#{i[0]}=#{get_to_httpget(i[1])}"
          end
        else
          data=""
          first=true
          for i in @variables
            unless first
              data+="&"
            else
              first=false
            end
            data+="#{i[0]}=#{post_to_httppost(i[1])}"
          end
        end
        data
      end
    end

    Code:
    #=======================================================================
    # Fonctions_Echanges écrit par Sphinx pour le système d'échanges en temps réel réalisé
    # avec la participation de Disscat, Samyh et Yuri
    # Contient de nouvelles méthodes ou des méthodes redéfinies pour ces classes déjà
    # déclarées :
    #   ¤ POKEMON_S::Pokemon
    #   ¤ POKEMON_S::Pokemon_Box
    #   ¤ POKEMON_S::Player
    #   ¤ Interpreter
    #   ¤ SpritePlan
    #   ¤ Integer
    #
    # Versions :
    #   ¤ version 2.0 : 24 Août 2011
    #
    # Credits demandes :
    #   ¤ Disscat (animation d'échange & d'attente et interface d'informations du pokémon recu)
    #   ¤ Samyh (fond de la scène d'échange)
    #   ¤ Sphinx (élaboration du système d'échange)
    #   ¤ Yuri (classes Socket et Web_File indispensables à ce système)
    #
    # Remerciemments égalemment aux autres membres qui ont bien voulu tester en
    # avant première ce système :
    #   ¤ Angi-Mk
    #   ¤ Emeraude
    #   ¤ Palbolsky
    #   ¤ Spiky
    #=======================================================================
    module POKEMON_S
      class Pokemon
        attr_reader :last_trainer_name
       
        alias new_pokemon initialize
        def initialize(id_data = 1, level = 1, shiny = false)
          new_pokemon(id_data, level, shiny)
          @last_trainer_name = Player.name
        end
       
        def isEchangeable?
          # Si le switch 20 est activé, tous les pokémons seront échangeables
          if not $game_switches[20] and (
            [
              # Mettez ici la liste des noms des pokémons (séparés par des virgules) que votre
              # joueur n'aura pas le droit d'échanger.
            ].include?(name)
          )
            return false
          end
         
          return true
        end
       
        def isRelachable?
          # Si le switch 20 est activé, tous les pokémons seront relachables
          if not $game_switches[20] and (
            [
              # Mettez ici la liste des noms des pokémons (séparés par des virgules) que votre
              # joueur n'aura pas le droit de relacher
            ].include?(name)
          )
            return false
          end
         
          return true
        end
       
        def nature_name
          return @nature[0]
        end
       
        def update_last_trainer_name
          @last_trainer_name = Player.name
        end
       
        # Fonction evolve_check modifiée pour ne faire évoluer par échange que les pokémons
        # qui doivent évoluer par échange.
        def evolve_check(mode = "", param = "")
          # Pas d'évolution
          if evolve_list[1] == [] or evolve_list[1] == nil or evolve_list[1][0] == ""
            return false
          end
         
          # [1, ["ONIGLALI", 42], ["MOMARTIK", ["stone", "PIERRE AUBE"], ["genre", "femelle"]]]
          int = Interpreter.new
          $ajout_poke = nil
          for i in 1..evolve_list.length-1
            check = true
           
            for j in 1..evolve_list[i].length-1
              # V0.7 : PSP teste chaque critère.
              #   Si le critère est bon, il passe au critère suivant (next), sinon,
              #   si aucun des critères na été respecté, l'évolution est rendue
              #   invalide (check = false)
              #   et on inspecte l'évolution possible suivante (break).
              #     A la fin, l'évolution est lancée car tous
              #     les critères ont été validés.
             
              if mode == "trade"
                # Echange
                if evolve_list[i][j] == "trade"
                  evolve_list[1][0] = evolve_list[i][0]
                  next
                end
              else
                # Evolution par niveau
                if evolve_list[i][j].type == Fixnum and @level >= evolve_list[i][j]
                  evolve_list[1][0] = evolve_list[i][0]
                  next
                end
               
                # Evolution par loyauté
                if evolve_list[i][j] == "loyal" and @loyalty > 220
                  evolve_list[1][0] = evolve_list[i][0]
                  next
                elsif evolve_list[i][j][0] == "loyal" and @loyalty > evolve_list[i][j][1]
                  evolve_list[1][0] = evolve_list[i][0]
                  next
                end
             
                # Evolution par lieu
                if evolve_list[i][j].is_a?(Array) and
                    evolve_list[i][j][0] == "place" and
                    evolve_list[i][j][1].include?($game_map.map_id)
                  evolve_list[1][0] = evolve_list[i][0]
                  next
                end
               
                # Evolution par apprentissage d'attaques
                if evolve_list[i][j].is_a?(Array) and
                    evolve_list[i][j][0] == "attaque" and
                    skills.include?(Skill_Info.id(evolve_list[i][j][1]))
                  evolve_list[1][0] = evolve_list[i][0]
                  next
                end
               
                # Evolution par objet tenu
                if evolve_list[i][j].is_a?(Array) and
                    evolve_list[i][j][0] == "item" and
                    @item_hold == Item.id(evolve_list[i][j][1])
                  evolve_list[1][0] = evolve_list[i][0]
                  next
                end
               
                # Evolution par genre
                if evolve_list[i][j].is_a?(Array) and evolve_list[i][j][0] == "genre"
                  if male? and evolve_list[i][j][1] == "male"
                    evolve_list[1][0] = evolve_list[i][0]
                    next
                  end
                  if female? and evolve_list[i][j][1] == "femelle"
                    evolve_list[1][0] = evolve_list[i][0]
                    next
                  end
                end
               
                # Evolution par periode
                if evolve_list[i][j].is_a?(Array) and evolve_list[i][j][0] == "periode"
                  if POKEMON_S.jour? and evolve_list[i][j][1] == "jour"
                    evolve_list[1][0] = evolve_list[i][0]
                    next
                  end
                  if POKEMON_S.nuit? and evolve_list[i][j][1] == "nuit"
                    evolve_list[1][0] = evolve_list[i][0]
                    next
                  end
                end
     
                # Evolution aléatoire <= A placer en tête (à la place normale du nom
                # de l'évolution)
                if evolve_list[i][j][0][0] == "aleatoire"
                  @alea_max = 0
                  for k in 0...evolve_list[i][j][0][1].size
                    @alea_max += evolve_list[i][j][0][1][k][1]
                  end
                  @alea = rand(@alea_max) + 1
                  for k in 0...evolve_list[i][j][0][1].size
                    @alea -= evolve_list[i][j][0][1][k][1]
                    if @alea <= 0
                      break
                    end
                  end
                  # L'évolution sera remplacée par le pokémon.
                  evolve_list[i][0] = evolve_list[i][j][0][1][k][0]
                end
               
                # Par pierre
                if evolve_list[i][j].is_a?(Array) and
                  evolve_list[i][j][0] == "stone" and
                  mode == "stone" and
                  evolve_list[i][j][1] == param
                  evolve_list[1][0] = evolve_list[i][0]
                  next
                end
               
                # Evolutions personnalisées
               
                # Compo équipe
                if evolve_list[i][j][0] == "compo_equipe"
                  tab = evolve_list[i][j][1]
                  cond_a_remplir = evolve_list[i][j][2]
                  if int.combinaison_possedees(tab,cond_a_remplir)
                    evolve_list[1][0] = evolve_list[i][0]
                    next
                  end
                end
               
                # Fusion de deux pokémons
                if evolve_list[i][j][0] == "fusion"
                  if evolve_list[i][j][1].type == String
                    evolve_list[i][j][1] = int.id_conversion(evolve_list[i][j][1])
                  end
                  for k in 0...$pokemon_party.size
                    if $pokemon_party.actors[k].id == evolve_list[i][j][1]
                      if @bool == false or @bool == nil
                        int.remove_pokemon(evolve_list[i][j][1])
                        @bool = true
                      end
                      break
                    end
                  end
                  if @bool
                    evolve_list[1][0] = evolve_list[i][0]
                    next
                  end
                end
               
                # Statistiques
                if evolve_list[i][j][0] == "stats"
                  stats = [@hp,@atk,@dfe,@spd,@ats,@dfs]
                  stats1 = []
                  stats2 = []
                  for s in 0...evolve_list[i][j][1].size
                    if evolve_list[i][j][1][s] != nil
                      stats1[s] = evolve_list[i][j][1][s].split(' ')[0].to_s
                      stats2[s] = evolve_list[i][j][1][s].split(' ')[1].to_s
                    else
                      stats1[s] = ">="
                      stats2[s] = 0
                    end
                    if stats2[s] == "HP"
                      stats2[s] = @hp
                    elsif stats2[s] == "ATK"
                      stats2[s] = @atk
                    elsif stats2[s] == "DFE"
                      stats2[s] = @dfe
                    elsif stats2[s] == "SPD"
                      stats2[s] = @spd
                    elsif stats2[s] == "ATS"
                      stats2[s] = @ats
                    elsif stats2[s] == "DFS"
                      stats2[s] = @dfs
                    else
                      stats2[s] = stats2[s].to_i
                    end
                  end
                  for s in 0...stats1.size
                    if stats1[s] == ">" and stats[s] > stats2[s]
                      @retour = true
                    elsif stats1[s] == ">=" and stats[s] >= stats2[s]
                      @retour = true
                    elsif stats1[s] == "==" and stats[s] == stats2[s]
                      @retour = true
                    elsif stats1[s] == "<=" and stats[s] <= stats2[s]
                      @retour = true
                    elsif stats1[s] == "<" and stats[s] < stats2[s]
                      @retour = true
                    elsif stats1[s] == "!=" and stats[s] != stats2[s]
                      @retour = true
                    elsif stats1[s] == "%" and stats[s] % stats2[s]
                      @retour = true
                    else
                      @retour = false
                      break
                    end
                  end
                  if @retour
                    evolve_list[1][0] = evolve_list[i][0]
                    next
                  end
                end
               
                # Variables / Switches
                if evolve_list[i][j][0] == "code"
                  for k in 0...evolve_list[i][j][1].size
                    if evolve_list[i][j][1][k][0] == "S" and evolve_list[i][j][1][k][1].type == Fixnum and [true,false,0,1].include?(evolve_list[i][j][1][k][2])
                      case evolve_list[i][j][1][k][2]
                      when 0
                        evolve_list[i][j][1][k][2] = false
                      when 1
                        evolve_list[i][j][1][k][2] = true
                      end
                      if $game_switches[evolve_list[i][j][1][k][1]] == evolve_list[i][j][1][k][2]
                        @retour = true
                      else
                        @retour = false
                      end
                    elsif evolve_list[i][j][1][k][0] == "V" and evolve_list[i][j][1][k][1].type == Fixnum and evolve_list[i][j][1][k][2].type == Fixnum and $game_variables[evolve_list[i][j][1][k][1]].to_s == evolve_list[i][j][1][k][2].to_s
                      @retour = true
                    else
                      @retour = false
                      break
                    end
                  end
                  if @retour
                    evolve_list[1][0] = evolve_list[i][0]
                    next
                  end
                end
     
                # Chance
                if evolve_list[i][j][0] == "chance"
                  if not(bool)
                    @lucky_list = [evolve_list[i][j][1].split('/')[0].to_i,evolve_list[i][j][1].split('/')[1].to_i]
                    @alea_lucky = rand(@lucky_list[1])
                    bool = true
                  end
                  if @alea_lucky < @lucky_list[0]
                    evolve_list[1][0] = evolve_list[i][0]
                    next
                  end
                end
               
                # Ajout de pokémons
                if evolve_list[i][j][0] == "ajout"
                  if not(bool)
                    $ajout_poke = []
                    if evolve_list[i][j][1].type == String
                      $ajout_poke.push([id_conversion(evolve_list[i][j][1]),@level])
                    elsif evolve_list[i][j][1].type == Fixnum
                      $ajout_poke.push([evolve_list[i][j][1],@level])
                    elsif evolve_list[i][j][1].type == Array
                      for k in evolve_list[i][j][1]
                        if $pokemon_party.size + evolve_list[i][j][1].index(k) < 6 or evolve_list[i][j][2] == "stocker"
                          if k.type == String
                            $ajout_poke.push([id_conversion(k),@level])
                          elsif k.type == Fixnum
                            $ajout_poke.push([k,@level])
                          end
                        end
                      end
                    end
                    bool = true
                  end
                  next
                end
              end
             
              check = false
              break
            end
           
            if check
              name = evolve_list[i][0]
              id = id_conversion(name)
              return id
            end
           
          end
         
          return false
        end
      end
     
      class Pokemon_Box
        def update_command_window
          @command_window.update
          @box = @box_viewer.box
          id = @box_viewer.index
          if @box_viewer.pokemon_pointed == nil and @mode == 2
            @command_window.disable_item(1)
          else
            @command_window.enable_item(1)
          end
          if ($pokemon_party.size == 1 and @mode == 1) or (@mode == 2 and @box_viewer.pokemon_pointed == nil)
            @command_window.disable_item(0)
            @command_window.disable_item(2)
            @command_window.disable_item(3)
          elsif ($pokemon_party.size == 6 and @mode == 2) or ($pokemon_party.box_full?(@box) and @mode == 1)
            @command_window.disable_item(0)
            @command_window.enable_item(2)
            @command_window.enable_item(3)
          elsif(@mode == 1 and $pokemon_party.actors[@box_party.index] != nil and not $pokemon_party.actors[@box_party.index].isRelachable?) or
             (@mode == 2 and $data_storage[@box][id] != nil and not $data_storage[@box][id].isRelachable?)
            @command_window.enable_item(0)
            @command_window.enable_item(2)
            @command_window.disable_item(3)
          else
            @command_window.enable_item(0)
            @command_window.enable_item(2)
            @command_window.enable_item(3)
          end

          # Mode pokémon sélectionné dans l'équipe
          if Input.trigger?(Input::C) and @mode == 1
            case @command_window.index
            when 0 # Transférer
              if $pokemon_party.size == 1
                $game_system.se_play($data_system.buzzer_se)
                return
              end
              if $pokemon_party.box_full?(@box)
                $game_system.se_play($data_system.buzzer_se)
                return
              end
              id = @box_party.index #indique la place du pokémon dans l'equipe
              id_store = $pokemon_party.store(id, @box)
              $game_system.se_play($data_system.decision_se)
              @command_window.active = false
              @command_window.visible = false
              @box_viewer.active = true
              @box_viewer.index = id_store
              @mode = 0

            when 1 # Résumé
              $game_system.se_play($data_system.decision_se)
              # Données [@mode, @box_party.index]
              scene = POKEMON_S::Pokemon_Status.new(@box_party.pokemon_pointed, -1, @z_level + 100, [@mode, @box_party.index])
              scene.main
              Graphics.transition
              return
            when 2 # Déplacer
              if $pokemon_party.size == 1
                $game_system.se_play($data_system.buzzer_se)
                return
              end
              @selected = [0, @box_party.index]
              @box_party.selected(@selected)
              $game_system.se_play($data_system.decision_se)
              @command_window.active = false
              @command_window.visible = false
              @box_party.active = true
              @mode = 0
              @box_party.refresh
              return

            when 3 # Relacher
              if $pokemon_party.size == 1 or not $pokemon_party.actors[@box_party.index].isRelachable?
                $game_system.se_play($data_system.buzzer_se)
                return
              end
              id = @box_party.index
              $game_system.se_play($data_system.decision_se)
              $pokemon_party.remove_id(id)
              @box_party.active = true
              @command_window.active = false
              @command_window.visible = false
              @mode = 0

              if $pokemon_party.actors[@box_party.index] == nil
                @box_party.index = $pokemon_party.size-1
              end

            when 4 # Annuler
              $game_system.se_play($data_system.decision_se)
              @command_window.active = false
              @command_window.visible = false
              @mode = 0
              @box_party.active = true
            end

            @box_party.refresh
            @box_viewer.refresh
            return
          end

          # Mode pokémon sélectionné dans la box
          if Input.trigger?(Input::C) and @mode == 2
            case @command_window.index
            when 0 # Transférer
              id = @box_viewer.index
              if $data_storage[@box][id] == nil or $pokemon_party.size == 6
                $game_system.se_play($data_system.buzzer_se)
                return
              end
              $pokemon_party.retrieve(id, @box)
              $game_system.se_play($data_system.decision_se)
              @command_window.active = false
              @command_window.visible = false
              @box_party.active = true
              @box_party.index = $pokemon_party.size - 1
              @mode = 0

            when 1 # Résumé
              id = @box_viewer.index
              if $data_storage[@box][id] == nil
                $game_system.se_play($data_system.buzzer_se)
                return
              end
              $game_system.se_play($data_system.decision_se)
              scene = POKEMON_S::Pokemon_Status.new(@box_viewer.pokemon_pointed, -1, @z_level + 100, [@mode, @box_viewer.index])
              scene.main
              Graphics.transition
              return
            when 2 # Deplacer
              id = @box_viewer.index
              if $data_storage[@box][id] == nil
                $game_system.se_play($data_system.buzzer_se)
                return
              end
              @selected = [@box, @box_viewer.index]
              @box_viewer.selected(@selected)
              $game_system.se_play($data_system.decision_se)
              @command_window.active = false
              @command_window.visible = false
              @mode = 0
              @box_viewer.active = true
              @box_viewer.refresh
              return

            when 3 # Relacher
              id = @box_viewer.index
              if $data_storage[@box][id] == nil or not $data_storage[@box][id].isRelachable?
                $game_system.se_play($data_system.buzzer_se)
                return
              end
              $game_system.se_play($data_system.decision_se)
              $data_storage[@box][id] = nil
              @box_viewer.active = true
              @mode = 0
              @command_window.active = false
              @command_window.visible = false

            when 4 # Annuler
              $game_system.se_play($data_system.decision_se)
              @command_window.active = false
              @command_window.visible = false
              @mode = 0
              @box_viewer.active = true
            end
            @box_party.refresh
            @box_viewer.refresh
            return
          end
        end
      end
     
      class Player
        def self.monCode
          return "#{sprintf('%010d', code)}_#{name}"
        end
      end
    end

    class Interpreter
      def echangesTempsReel
        $scene = Scene_Echanges.new
      end
    end

    class SpritePlan
      def ajouterSprite(no_sprite, sprite)
        @sprites[no_sprite] = sprite
      end
    end

    class Integer
      def bornes(min, max)
        return [min, [self, max].min].max
      end
    end

    Code:
    #=======================================================================
    # Scene_Echanges écrit par Sphinx pour le système d'échanges en temps réel réalisé
    # avec la participation de Disscat, Samyh et Yuri
    # Contient les nouvelles classes :
    #   ¤ POKEMON_S::Scene_Echanges # Scène principale
    #   ¤ POKEMON_S::Select_Player # Classe utilisée pour la sélection du joueur avec qui
    #                                                              échanger
    #   ¤ Window_Choice # Fenêtre utilisée pour lister les joueurs "connectés"
    #
    # Versions :
    #   ¤ version 1.0 : 13 Août 2011
    #   ¤ version 2.0 : 24 Août 2011
    #
    # Credits demandes :
    #   ¤ Disscat (animation d'échange & d'attente et interface d'informations du pokémon recu)
    #   ¤ Samyh (fond de la scène d'échange)
    #   ¤ Sphinx (élaboration du système d'échange)
    #   ¤ Yuri (classes Socket et Web_File indispensables à ce système)
    #
    # Remerciemments égalemment aux autres membres qui ont bien voulu tester en
    # avant première ce système :
    #   ¤ Angi-Mk
    #   ¤ Emeraude
    #   ¤ Palbolsky
    #   ¤ Spiky
    #=======================================================================
    module POKEMON_S
      # L'adresse complète vers le fichier index.php sans le http://
      URL = "localhost/echanges/index.php"
     
      class Scene_Echanges
        def initialize(z_level = 500)
          @z_level = z_level
          @spriteplan = SpritePlan.new(0, 0, 640, 480)
          # Fond
          @spriteplan[2] = "echange_fond.png"
          @spriteplan[2].z = @z_level
          # Boite de messages
          @spriteplan[3] = "messagedummy.png"
          @spriteplan[3].x = 0
          @spriteplan[3].y = 336
          @spriteplan[3].z = @z_level + 50
        end
       
        def main
          @on_close = ""
          begin
            Audio.bgm_play("Audio/BGM/PkmRS-MtChimney", 80, 100)
            if draw_text("Bonjour et bienvenue dans le centre d'échanges. rtn Avant d'effectuer un échange, nous devons sauvegarder votre partie. rtn Voulez-vous continuer ?", ["OUI", "NON"]) == 0
              forcer_sauvegarde
              draw_text("Votre partie a été sauvegardée.")
              @selectPlayer = Select_Player.new(@z_level + 50)
              @selected = @selectPlayer.main.to_s
              @selectPlayer.dispose
              if @selected != ""
                draw_text("Nous allons vous connecter au serveur. rtn Veuillez patienter s'il vous plait...")
                @on_close = "cancel"
                retour = animation_attente(true, {"mode" => "select", "monCode" => Player.monCode, "sonCode" => @selected})
                if retour
                  loop do
                    draw_text("Veuillez choisir le Pokémon que vous souhaitez envoyer.")
                    index = appel_menu_equipe
                    if index == -1 and draw_text("Voulez-vous annuler l'échange?", ["OUI", "NON"]) == 0
                      draw_text("Vous avez annulé l'échange.")
                      fin_scene
                      return false
                    elsif index >= 0
                      @pokemon_envoye = $pokemon_party.actors[index]
                      if @pokemon_envoye.isEchangeable?
                        retour = animation_attente(true, {"mode" => "sent", "monCode" => Player.monCode, "sonCode" => @selected, "pokemon" => Marshal.encrypt([TRADEGROUP, @selected, @pokemon_envoye], nil, Player.monCode, @selected)}, {"mode" => "update", "monCode" => Player.monCode, "sonCode" => @selected})
                        if retour
                          begin
                            tmp = Marshal.uncrypt(retour, false, @selected, Player.monCode)
                            if tmp.is_a?(Array)
                              tradegroup = tmp[0]
                              if TRADEGROUP == tradegroup
                                myCode = tmp[1]
                                if Player.monCode == myCode
                                  @pokemon_recu = tmp[2]
                                else
                                  draw_text("Ce pokémon ne vous est pas destiné. L'échange a été annulé.")
                                  fin_scene
                                  return false
                                end
                              else
                                draw_text("Le pokémon envoyé n'appartient pas à votre groupe d'échanges. L'échange a été annulé.")
                                fin_scene
                                return false
                              end
                            else
                              draw_text("Une erreur est survenue au cours du transfert. L'échange a été annulé.")
                              fin_scene
                              return false
                            end
                          rescue
                            draw_text("Une erreur est survenue au cours du transfert. L'échange a été annulé.")
                            fin_scene
                            return false
                          end
                         
                          informations_pokemon_recu(@pokemon_recu)
                          if draw_text("Voulez vous recevoir ce pokémon ?", ["OUI", "NON"]) == 0
                            @spriteplan[14].visible = false
                            @spriteplan[15].visible = false
                            retour = animation_attente(true, {"mode" => "valid", "monCode" => Player.monCode, "sonCode" => @selected})
                            if retour == "true"
                              @on_close = "valid"
                              $pokemon_party.remove(@pokemon_envoye)
                              $pokemon_party.add(@pokemon_recu)
                              forcer_sauvegarde
                             
                              retour = animation_attente(true, {"mode" => "synchro", "monCode" => Player.monCode, "sonCode" => @selected})
                              if retour
                                animation_echange(@pokemon_envoye, @pokemon_recu)
                                check = @pokemon_recu.evolve_check("trade")
                                if check != false
                                  Graphics.freeze
                                  scene = POKEMON_S::Pokemon_Evolve.new(@pokemon_recu, check, @z_level + 500, true)
                                  scene.main
                                  Graphics.transition
                                end
                                forcer_sauvegarde
                                draw_text("Votre partie a été sauvegardée.")
                                fin_scene
                                return true
                              else
                                $pokemon_party.remove(@pokemon_recu)
                                $pokemon_party.actors.insert(index, @pokemon_envoye)
                                forcer_sauvegarde
                                draw_text("L'échange a été annulé.")
                                fin_scene
                                return false
                              end
                            else
                              draw_text("L'échange a été annulé.")
                              fin_scene
                              return false
                            end
                          else
                            @spriteplan[14].visible = false
                            @spriteplan[15].visible = false
                            retour = animation_attente(true, {"mode" => "cancel", "monCode" => Player.monCode, "sonCode" => @selected}, {"mode" => "cancel", "monCode" => Player.monCode, "sonCode" => @selected})
                            if retour
                              draw_text("Vous avez annulé l'échange.")
                              fin_scene
                              return false
                            end
                          end
                        else
                          draw_text("L'échange a été annulé.")
                          fin_scene
                          return false
                        end
                      else
                        draw_text("Ce pokémon n'est pas échangeable.")
                        if draw_text("Voulez-vous choisir un autre pokémon ?", ["OUI", "NON"]) == 1
                          draw_text("Vous avez annulé l'échange.")
                          fin_scene
                          return false
                        end
                      end
                    end
                  end
                else
                  draw_text("Impossible de vous connecter au serveur.")
                  fin_scene
                  return false
                end
              else
                draw_text("Vous avez quitté le centre.")
                fin_scene
                return false
              end
            else
              draw_text("Vous devez sauvegarder votre partie avant de pouvoir échanger un pokémon.")
              fin_scene(false)
              return false
            end
          rescue NoMethodError => nme
            if nme.message == "undefined method `size' for nil:NilClass"
              draw_text("Impossible de vous connecter au serveur. Il se peut que vous n'ayez pas accès à internet. Si vous pouvez accéder à internet, assurez vous que le programme RGSS Player ait également le droit d'y accéder. rtn Si RGSS Player a bien le droit d'accéder à internet, veuillez en informer le créateur de ce jeu.")
              fin_scene(false)
            else
              draw_text("Une erreur est survenue au cours de l'échange. Vous avez été déconnecté.")
              fin_scene(false)
              EXC::error_handler(nme)
            end
          rescue SystemExit
            case @on_close
              when "cancel"
                retour = animation_attente(true, {"mode" => "cancel", "monCode" => Player.monCode, "sonCode" => @selected})
                if retour
                  forcer_sauvegarde
                  draw_text("Vous avez annulé l'échange.")
                  fin_scene
                  raise
                end
              when "valid"
                loop do
                  begin
                    animation_attente(false, {"mode" => "synchro", "monCode" => Player.monCode, "sonCode" => @selected})
                    break
                  rescue SystemExit
                  end
                end
                if retour
                  if $pokemon_party.actors.include?(@pokemon_envoye)
                    $pokemon_party.remove(@pokemon_envoye)
                  end
                  unless $pokemon_party.actors.include?(@pokemon_recu)
                    $pokemon_party.add(@pokemon_recu)
                  end
                  forcer_sauvegarde
                  draw_text("L'échange est terminé. Vous avez fermé le jeu, votre pokémon n'évoluera donc pas, même s'il devrait.")
                  fin_scene
                  raise
                else
                  $pokemon_party.remove(@pokemon_recu)
                  $pokemon_party.actors.insert(index, @pokemon_envoye)
                  forcer_sauvegarde
                  draw_text("L'échange a été annulé.")
                  fin_scene
                  raise
                end
              else
                fin_scene(false)
                raise
            end
          rescue Exception => e
            draw_text("Une erreur est survenue au cours de l'échange. Vous avez été déconnecté.")
            fin_scene(false)
            EXC::error_handler(e)
          end
        end
       
        def fin_scene(deleteTrace = true)
          if deleteTrace
            draw_text("Déconnexion du serveur...")
            animation_attente(false, {"mode" => "delete", "monCode" => Player.monCode, "sonCode" => @selected}, {"mode" => "delete", "monCode" => Player.monCode, "sonCode" => @selected})
          end
          Audio.bgm_stop
          @spriteplan[1].dispose unless @spriteplan[1].disposed?
          @spriteplan[2].dispose
          @spriteplan[3].dispose
          @spriteplan[14].dispose
          @spriteplan[15].dispose
          $scene = Scene_Map.new
          Graphics.transition
        end
       
        def coupure_mots(mot)
          temp_bitmap2 = Bitmap.new(1, 1)
          temp_bitmap2.font.name = $fontface
          temp_bitmap2.font.size = $fontsize
          for c in 0...mot.size
            if temp_bitmap2.text_size(mot[0..c] + "-").width >= 560
              break
            end
          end
          temp_bitmap2.clear
          return [mot[0...c] + "-","-" + mot[c...mot.size]]
        end
       
        def draw_text(text, choix = [])
          return if text.type != String or text == ""
          text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
          text.gsub!(/\\[Pp]\[([0-9]+)\]/) { $string[$1.to_i] }
          text.gsub!(/\\[Nn]\[([0-9]+)\]/) { ($game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : "") }
          temp_bitmap = Bitmap.new(1, 1)
          temp_bitmap.font.name = $fontface
          temp_bitmap.font.size = $fontsize
          if text.type != String
            text = text.to_s
          end
          if text == ""
            return false
          end
          text = text.split(' ')
          if temp_bitmap.text_size(text[0]).width <= 560
            texte = [text[0]]
            j = 0
          else
            mot = coupure_mots(text[0])
            texte = [mot[0],mot[1]]
            j = 1
          end
          for i in 1...text.size
            if temp_bitmap.text_size(text[i]).width > 560
              mot = coupure_mots(texte[j] + " " + text[i])
              texte[j] = mot[0]
              j += 1
              texte[j] = mot[1]
            elsif temp_bitmap.text_size(texte[j] + " " + text[i]).width > 560
              j += 1
              texte[j] = text[i]
            elsif text[i] == "rtn"
              j += 1
              texte[j] = ""
              next
            elsif texte[j].size == 0
              texte[j] += text[i]
            else
              texte[j] += " " + text[i]
            end
          end
          temp_bitmap.clear
          scene = Afficher_Message.new(texte, 0, Color.new(60, 60, 60), 0, choix)
          return scene.main
        end
       
        def animation_attente(afficher_persian, variables_ini, variables_upd = variables_ini)
          Graphics.freeze
          if afficher_persian
            @spriteplan[1] = "Persian_00.png"
            @spriteplan[1].x = 0
            @spriteplan[1].y = 0
            @spriteplan[1].z = @z_level + 300
          end
          Graphics.transition
          wf = Web_File.new(URL, variables_ini)
          retour = wf.read
         
          if retour != ""
            Graphics.freeze
            @spriteplan[1].dispose
            Graphics.transition
            return retour
          end
          i = 1
         
          loop do
            if i % 3 == 0 and afficher_persian
              @spriteplan[1] = "Persian_#{sprintf('%02d', (i / 3) % 12)}.png"
            end
            if i % 10 == 0
              wf = Web_File.new(URL, variables_upd)
              retour = wf.read
            end
            Graphics.update
            Input.update
            if retour != ""
              Graphics.freeze
              @spriteplan[1].dispose
              Graphics.transition
              return retour
            end
            if Input.trigger?(Input::B)
              Graphics.freeze
              @spriteplan[1].dispose
              Graphics.transition
              return false
            end
            i += 1
          end
        end
       
        def animation_echange(pokemon_envoye, pokemon_recu)
          Graphics.freeze
         
          # Interface 1-1
          @spriteplan[4] = "echange_interface1-1.png"
          @spriteplan[4].x = 29
          @spriteplan[4].y = 94
          @spriteplan[4].z = @z_level + 250
          @spriteplan[4].visible = false
          # Interface 1-2
          @spriteplan[5] = "echange_interface1-2.png"
          @spriteplan[5].x = 55
          @spriteplan[5].y = 120
          @spriteplan[5].z = @z_level + 150
          @spriteplan[5].visible = false
          # Interface 1-3
          @spriteplan[6] = "echange_interface1-3.png"
          @spriteplan[6].x = 291
          @spriteplan[6].y = 175
          @spriteplan[6].z = @z_level + 50
          @spriteplan[6].visible = false
          # Interface 2
          @spriteplan[7] = "echange_interface2.png"
          @spriteplan[7].x = 0
          @spriteplan[7].y = 86
          @spriteplan[7].z = @z_level + 50
          @spriteplan[7].visible = false
          # Interface 3 n°1
          @spriteplan[8] = "echange_interface3.png"
          @spriteplan[8].x = 0
          @spriteplan[8].y = 0
          @spriteplan[8].z = @z_level + 100
          @spriteplan[8].visible = false
          # Interface 3 n°2
          @spriteplan[9] = "echange_interface3.png"
          @spriteplan[9].x = 0
          @spriteplan[9].y = 0
          @spriteplan[9].z = @z_level + 100
          @spriteplan[9].visible = false
          # Barre de progression
          @spriteplan[10] = "echange_barre.png"
          @spriteplan[10].x = 67
          @spriteplan[10].y = 298
          @spriteplan[10].z = @z_level + 300
          @spriteplan[10].zoom_x = 0
          # Sprite du pokémon envoyé
          tmpSprite = Sprite.new
          tmpSprite.x = -500
          tmpSprite.y = -500
          tmpSprite.zoom_x = 0
          tmpSprite.zoom_y = 0
          tmpSprite.z = @z_level + 200
          tmpSprite.bitmap = RPG::Cache.battler(pokemon_envoye.battler_face, 0)
          @spriteplan.ajouterSprite(11, tmpSprite)
          # Icone du pokémon envoyé
          tmpSprite = Sprite.new
          tmpSprite.x = -500
          tmpSprite.y = -500
          tmpSprite.zoom_x = 0
          tmpSprite.zoom_y = 0
          tmpSprite.z = @z_level + 200
          tmpSprite.bitmap = RPG::Cache.battler(pokemon_envoye.icon, 0)
          @spriteplan.ajouterSprite(12, tmpSprite)
          # Icone du pokémon recu
          tmpSprite = Sprite.new
          tmpSprite.x = -500
          tmpSprite.y = -500
          tmpSprite.zoom_x = 0
          tmpSprite.zoom_y = 0
          tmpSprite.z = @z_level + 200
          tmpSprite.bitmap = RPG::Cache.battler(pokemon_recu.icon, 0)
          @spriteplan.ajouterSprite(13, tmpSprite)
          # Sprite du pokémon recu
          tmpSprite = Sprite.new
          tmpSprite.x = -500
          tmpSprite.y = -500
          tmpSprite.zoom_x = 0
          tmpSprite.zoom_y = 0
          tmpSprite.z = @z_level + 200
          tmpSprite.bitmap = RPG::Cache.battler(pokemon_recu.battler_face, 0)
          @spriteplan.ajouterSprite(16, tmpSprite)
          Graphics.transition
         
          wait(50)
         
          Graphics.freeze
          @spriteplan[4].visible = true
          @spriteplan[5].visible = true
          @spriteplan[6].visible = true
          Graphics.transition
         
          Graphics.freeze
          @spriteplan[11].zoom_x = 0.8
          @spriteplan[11].zoom_y = 0.8
          @spriteplan[11].x = 55 + (212 - @spriteplan[11].bitmap.width * @spriteplan[11].zoom_x) / 2
          @spriteplan[11].y = 120 + (144 - @spriteplan[11].bitmap.height * @spriteplan[11].zoom_y) / 2
          Graphics.transition
         
          Audio.bgm_stop
         
          draw_text("Au revoir, #{@pokemon_envoye.given_name}.")
          if FileTest.exist?(@pokemon_envoye.cry)
            Audio.se_play(@pokemon_envoye.cry)
          end
         
          wait(10)
          Audio.bgm_play("Audio/BGM/PkmRS-Evolving", 80, 100)
         
          while @spriteplan[10].zoom_x < 1
            @spriteplan[10].zoom_x += 0.0075
            if @spriteplan[10].zoom_x < 0.5
              @spriteplan[11].zoom_x -= 0.012
              @spriteplan[11].zoom_y -= 0.012
              @spriteplan[11].x = 55 + (212 - @spriteplan[11].bitmap.width * @spriteplan[11].zoom_x) / 2
              @spriteplan[11].y = 120 + (144 - @spriteplan[11].bitmap.height * @spriteplan[11].zoom_y) / 2
            elsif @spriteplan[10].zoom_x == 0.5
              @spriteplan[11].visible = false
              @spriteplan[12].zoom_x = 0
              @spriteplan[12].zoom_y = 0.015
              @spriteplan[12].x = 55 + (212 - @spriteplan[12].bitmap.width * @spriteplan[12].zoom_x) / 2
              @spriteplan[12].y = 120 + (144 - @spriteplan[12].bitmap.height * @spriteplan[12].zoom_x) / 2
            elsif @spriteplan[10].zoom_x > 0.5
              @spriteplan[12].zoom_x += 0.015
              @spriteplan[12].zoom_y += 0.015
              @spriteplan[12].x = 55 + (212 - @spriteplan[12].bitmap.width * @spriteplan[12].zoom_x) / 2
              @spriteplan[12].y = 120 + (144 - @spriteplan[12].bitmap.height * @spriteplan[12].zoom_x) / 2
            end
            Graphics.update
          end
         
          wait(20)
         
          vitesse = 1
          @spriteplan[8].x = @spriteplan[12].x - ((@spriteplan[8].bitmap.width - (@spriteplan[12].bitmap.width * @spriteplan[12].zoom_x)) / 2)
          @spriteplan[8].y = 158
          @spriteplan[8].visible = true
          while @spriteplan[8].x <= 640
            if @spriteplan[12].zoom_x > 0.25 and @spriteplan[12].zoom_y > 0.25
              @spriteplan[12].zoom_x -= 0.0075
              @spriteplan[12].zoom_y -= 0.0075
              @spriteplan[12].y = 120 + (144 - @spriteplan[12].bitmap.height * @spriteplan[12].zoom_x) / 2
              @spriteplan[8].x = @spriteplan[12].x - ((@spriteplan[8].bitmap.width - (@spriteplan[12].bitmap.width * @spriteplan[12].zoom_x)) / 2)
              @spriteplan[8].y = 158
            end
            if @spriteplan[12].x >= 267 and @spriteplan[12].x < 270
              vitesse = 5
              Audio.se_play("Audio/SE/Pokemove")
            end
            @spriteplan[8].x += 3 * vitesse
            @spriteplan[12].x += 3 * vitesse
            Graphics.update
          end
         
          wait(20)
         
          Graphics.freeze
          @spriteplan[4].visible = false
          @spriteplan[5].visible = false
          @spriteplan[6].visible = false
          @spriteplan[7].visible = true
          @spriteplan[10].visible = false
          @spriteplan[11].visible = false
          @spriteplan[8].x = -@spriteplan[8].bitmap.width
          @spriteplan[8].y = 69
          @spriteplan[12].x = @spriteplan[8].x + ((@spriteplan[8].bitmap.width - (@spriteplan[12].bitmap.width * @spriteplan[12].zoom_x)) / 2)
          @spriteplan[12].y = 86 + (34 - @spriteplan[12].bitmap.height * @spriteplan[12].zoom_x) / 2
          @spriteplan[9].visible = true
          @spriteplan[9].x = 640
          @spriteplan[9].y = 173
          @spriteplan[13].zoom_x = 0.5
          @spriteplan[13].zoom_y = 0.5
          @spriteplan[13].x = @spriteplan[9].x + ((@spriteplan[9].bitmap.width - (@spriteplan[13].bitmap.width * @spriteplan[13].zoom_x)) / 2)
          @spriteplan[13].y = 192 + (34 - @spriteplan[13].bitmap.height * @spriteplan[13].zoom_x) / 2
          Graphics.transition
         
          wait(20)
         
          while @spriteplan[8].x <= 640
            @spriteplan[8].x += 15
            @spriteplan[12].x += 15
            @spriteplan[9].x -= 15
            @spriteplan[13].x -= 15
            Graphics.update
          end
         
          wait(20)
         
          Graphics.freeze
          @spriteplan[4].visible = true
          @spriteplan[5].visible = true
          @spriteplan[6].visible = true
          @spriteplan[7].visible = false
          @spriteplan[10].visible = true
          @spriteplan[8].visible = false
          @spriteplan[12].visible = false
          @spriteplan[10].zoom_x = 0
          @spriteplan[9].x = 640
          @spriteplan[9].y = 158
          @spriteplan[13].x = @spriteplan[9].x + ((@spriteplan[9].bitmap.width - (@spriteplan[13].bitmap.width * @spriteplan[13].zoom_x)) / 2)
          @spriteplan[13].y = 120 + (144 - @spriteplan[13].bitmap.height * @spriteplan[13].zoom_x) / 2
          Graphics.transition
         
          vitesse = 5
          while @spriteplan[13].x >= 55 + (212 - @spriteplan[13].bitmap.width * @spriteplan[13].zoom_x) / 2
            if @spriteplan[13].x <= 270 and @spriteplan[13].zoom_x < 1 and @spriteplan[13].zoom_y < 1
              @spriteplan[13].zoom_x += 0.0075
              @spriteplan[13].zoom_y += 0.0075
              @spriteplan[13].y = 120 + (144 - @spriteplan[13].bitmap.height * @spriteplan[13].zoom_x) / 2
            end
            if @spriteplan[13].x >= 267 and @spriteplan[13].x < 282
              Audio.se_play("Audio/SE/Pokemove")
              vitesse = 1
              @spriteplan[9].visible = false
            end
            @spriteplan[9].x -= 3 * vitesse
            @spriteplan[13].x -= 3 * vitesse
            Graphics.update
          end
         
          wait(20)
         
          while @spriteplan[10].zoom_x < 1
            @spriteplan[10].zoom_x += 0.0075
            if @spriteplan[10].zoom_x < 0.5
              @spriteplan[13].zoom_x -= 0.015
              @spriteplan[13].zoom_y -= 0.015
              @spriteplan[13].x = 55 + (212 - @spriteplan[13].bitmap.width * @spriteplan[13].zoom_x) / 2
              @spriteplan[13].y = 120 + (144 - @spriteplan[13].bitmap.height * @spriteplan[13].zoom_y) / 2
            elsif @spriteplan[10].zoom_x == 0.5
              @spriteplan[13].visible = false
              @spriteplan[16].zoom_x = 0
              @spriteplan[16].zoom_y = 0.012
              @spriteplan[16].x = 55 + (212 - @spriteplan[16].bitmap.width * @spriteplan[16].zoom_x) / 2
              @spriteplan[16].y = 120 + (144 - @spriteplan[16].bitmap.height * @spriteplan[16].zoom_x) / 2
            elsif @spriteplan[10].zoom_x > 0.5
              @spriteplan[16].zoom_x += 0.012
              @spriteplan[16].zoom_y += 0.012
              @spriteplan[16].x = 55 + (212 - @spriteplan[16].bitmap.width * @spriteplan[16].zoom_x) / 2
              @spriteplan[16].y = 120 + (144 - @spriteplan[16].bitmap.height * @spriteplan[16].zoom_x) / 2
            end
            Graphics.update
          end
         
          Audio.bgm_stop
          wait(10)
         
          if FileTest.exist?(@pokemon_recu.cry)
            Audio.se_play(@pokemon_recu.cry)
          end
         
          draw_text("#{@pokemon_recu.last_trainer_name} vous a envoyé #{@pokemon_recu.given_name}.")
          @pokemon_recu.update_last_trainer_name
         
          Audio.me_play("Audio/ME/Caughtjingle", 80, 100)
          wait(80)
          Audio.bgm_play("Audio/BGM/PkmRS-MtChimney", 80, 100)
         
          Graphics.freeze
          @spriteplan[4].dispose
          @spriteplan[5].dispose
          @spriteplan[6].dispose
          @spriteplan[7].dispose
          @spriteplan[10].dispose
          @spriteplan[8].dispose
          @spriteplan[9].dispose
          @spriteplan[11].dispose
          @spriteplan[12].dispose
          @spriteplan[13].dispose
          @spriteplan[16].dispose
        end
       
        def wait(frame)
          for i in 0..frame
            Graphics.update
          end
        end
       
        def wait_hit
          loop do
            Graphics.update
            Input.update
            if Input.trigger?(Input::C)
              break
            end
          end
        end
       
        def informations_pokemon_recu(pokemon_recu)
          sprite1 = Sprite.new
          sprite1.x = 160
          sprite1.y = 73
          sprite1.z = @z_level + 50
          sprite1.bitmap = RPG::Cache.picture("echange_interface4.png")
         
          sprite2 = Sprite.new
          sprite2.x = 160
          sprite2.y = 73
          sprite2.z = @z_level + 100
          sprite2.bitmap = Bitmap.new(sprite1.bitmap.width, sprite1.bitmap.height)
          sprite2.bitmap.font.name = $fontface
          sprite2.bitmap.font.color = Color.new(60, 60, 60)
         
          sprite2.bitmap.stretch_blt(Rect.new(13, 13, 80, 80), RPG::Cache.battler("#{pokemon_recu.battler_face}", 0), Rect.new(0, 0, 160, 160), 255)
          sprite2.bitmap.font.size = 14
          sprite2.bitmap.font.bold = true
          sprite2.bitmap.draw_text(107, 4, 102, 14, "#{pokemon_recu.name}", 1)
          sprite2.bitmap.draw_text(214, 4, 102, 14, "No #{pokemon_recu.id}", 1)
          sprite2.bitmap.font.bold = false
          sprite2.bitmap.draw_text(107, 32, 102, 14, "#{pokemon_recu.given_name}", 1)
          sprite2.bitmap.draw_text(214, 32, 102, 14, "#{((pokemon_recu.gender == 1 ? 'Male' : pokemon_recu.gender == 2 ? 'Femelle' : 'Inconnu'))}", 1)
          sprite2.bitmap.draw_text(107, 60, 102, 14, "#{pokemon_recu.trainer_name}", 1)
          sprite2.bitmap.draw_text(214, 60, 102, 14, "#{pokemon_recu.trainer_id}", 1)
          sprite2.bitmap.draw_text(107, 88, 102, 14, "#{pokemon_recu.nature_name}", 1)
          sprite2.bitmap.draw_text(214, 88, 102, 14, "#{pokemon_recu.ability_name}", 1)
          sprite2.bitmap.draw_text(30, 106, 48, 14, "Nv : #{pokemon_recu.level}", 1)
          sprite2.bitmap.draw_text(7, 131, 48, 14, "PVS : #{pokemon_recu.max_hp}", 1)
          sprite2.bitmap.draw_text(59, 131, 48, 14, "ATK : #{pokemon_recu.ats}", 1)
          sprite2.bitmap.draw_text(111, 131, 48, 14, "DFE : #{pokemon_recu.dfe}", 1)
          sprite2.bitmap.draw_text(164, 131, 48, 14, "ATS : #{pokemon_recu.ats}", 1)
          sprite2.bitmap.draw_text(216, 131, 48, 14, "DFS : #{pokemon_recu.dfs}", 1)
          sprite2.bitmap.draw_text(268, 131, 48, 14, "SPD : #{pokemon_recu.spd}", 1)
          sprite2.bitmap.draw_text(7, 155, 151, 33, "#{(pokemon_recu.skills_set[0].nil? ? '-------' : pokemon_recu.skills_set[0].name)}", 1)
          sprite2.bitmap.draw_text(164, 155, 151, 33, "#{(pokemon_recu.skills_set[1].nil? ? '-------' : pokemon_recu.skills_set[1].name)}", 1)
          sprite2.bitmap.draw_text(7, 199, 151, 33, "#{(pokemon_recu.skills_set[2].nil? ? '-------' : pokemon_recu.skills_set[2].name)}", 1)
          sprite2.bitmap.draw_text(164, 199, 151, 33, "#{(pokemon_recu.skills_set[3].nil? ? '-------' : pokemon_recu.skills_set[3].name)}", 1)
         
          @spriteplan.ajouterSprite(14, sprite1)
          @spriteplan.ajouterSprite(15, sprite2)
         
          return true
        end
       
        def appel_menu_equipe
          Graphics.freeze
          scene = Pokemon_Party_Menu.new(0, 10000, "selection")
          scene.main
          data = scene.return_data
          scene = nil
          Graphics.transition
          return data
        end
       
        def forcer_sauvegarde
          if not SAVEBOUNDSLOT
            return
          end
          captured = 0
          for i in 1..$data_pokedex.length-1
            if $data_pokedex[i][1]
              captured += 1
            end
          end
          $read_data = [Player.name, Player.id, captured, $map_link]
          filename = "Save#{POKEMON_S::_SAVESLOT + 1}.rxdata"
          file = File.open(filename, "wb")
          characters = []
          for i in 0...$game_party.actors.size
            actor = $game_party.actors[i]
            characters.push([actor.character_name, actor.character_hue])
          end
          Marshal.dump(characters, file)
          Marshal.dump(Graphics.frame_count, file)
          $game_system.save_count += 1
          $game_system.magic_number = $data_system.magic_number
          game_system = $game_system.clone
          game_system.reset_interpreter
          Marshal.dump(game_system, file)
          Marshal.dump($game_switches, file)
          Marshal.dump($game_variables, file)
          Marshal.dump($game_self_switches, file)
          Marshal.dump($game_screen, file)
          Marshal.dump($game_actors, file)
          Marshal.dump($game_party, file)
          Marshal.dump($game_troop, file)
          Marshal.dump($game_map, file)
          Marshal.dump($game_player, file)
          Marshal.dump($read_data, file)
          Marshal.dump($pokemon_party, file)
          Marshal.dump($random_encounter, file)
          Marshal.dump($data_pokedex, file)
          Marshal.dump($data_storage, file)
          Marshal.dump($battle_var, file)
          Marshal.dump($existing_pokemon, file)
          Marshal.dump($string, file)
          file.close
        end
      end
     
      class Select_Player
        SLEEPTPS = 0.1
       
        def initialize(z_level = 500)
          @wc = Window_Choice.new(10, 60, 620, 266, *listePseudos)
          @wc.z = z_level
          @wc.disable_item(@liste.index(Player.monCode))
          @thread = Thread.new {
            begin
              loop do
                @wc.replaceCommands(*listePseudos)
                sleep(SLEEPTPS)
              end
            rescue Exception => e
              EXC::error_handler(e)
              raise
            end
          }
        end
       
        def main
          loop do
            Graphics.update
            Input.update
            @wc.update
            if Input.trigger?(Input::B)
              @wc.dispose
              return nil
            elsif Input.trigger?(Input::C)
              @item = @wc.commandSelected
              if @item.nil? or @item == Player.monCode
                $game_system.se_play($data_system.buzzer_se)
              else
                $game_system.se_play($data_system.decision_se)
                break
              end
            end
          end
          return @item
        end
       
        def listePseudos
          wf = Web_File.new(URL, {"mode" => "connect", "monCode" => Player.monCode})
          retour = wf.read
          begin
            @liste = eval(retour)
          rescue SyntaxError
            @liste = []
          end
          @liste.sort! { |a, b| a.split("_")[1] <= b.split("_")[1] } rescue
          return @liste
        end
       
        def dispose
          @thread.kill
          @wc.dispose
        end
      end
    end

    class Window_Choice < Window_Command
      include POKEMON_S
     
      def initialize(x, y, w, h, *items)
        @x = x
        @y = y
        @maxWidth = w
        @maxHeight = h
        @values = items
        @commands = affichage
       
        @frames = 0
        @bitmap = Bitmap.new(1, 1)
        @bitmap.font.name = $fontface
        @bitmap.font.size = $fontsize
        @flecheHaut = Sprite.new
        @flecheHaut.visible = false
        @flecheHaut.z = 1000
        @flecheHaut.bitmap = RPG::Cache.picture("fleche_haut")
        @flecheBas = Sprite.new
        @flecheBas.visible = false
        @flecheBas.z = 1000
        @flecheBas.bitmap = RPG::Cache.picture("fleche_bas")
       
        cw = columnWidth
        @row_max = (h / 32) - 1
        @column_max = [@maxWidth / cw, (length / @row_max) + (length % @row_max == 0 ? 0 : 1)].min
        width = (cw * @column_max) + 32
        super(width, @commands, $fontsize, @column_max)
       
        h = ((length / @column_max) + (length % @column_max == 0 ? 0 : 1) * 5) * 32
        self.contents = Bitmap.new(w, h)
        self.contents.font.name = $fontface
        self.contents.font.size = $fontsize
       
        positionnement
        refresh
      end
     
      def positionnement
        cw = columnWidth
        @column_max = [@maxWidth / cw, (length / @row_max) + (length % @row_max == 0 ? 0 : 1)].min
       
        self.width = (cw * @column_max) + 32
        self.height = ([(length / @column_max) + (length % @column_max == 0 ? 0 : 1), @row_max].min + 1) * 32
        self.x = @x + (@maxWidth - self.width) / 2
        self.y = @y + (@maxHeight - self.height) / 2
        self.oy = [self.oy, row_max * 32 - (self.height - 32)].min
       
        @frames = 0
        @flecheHaut.x = self.x + (self.width / 2) - 4
        @flecheHaut.y = self.y + 12
        @flecheBas.x = self.x + (self.width / 2) - 4
        @flecheBas.y = self.y + self.height - 20
      end
     
      def columnWidth
        width = 0
        for arg in @commands
          w = @bitmap.text_size(arg).width
          width = w if w > width
        end
        return width + 32
      end
     
      def update
        super
       
        @flecheHaut.visible = self.oy > 0
        @flecheBas.visible = self.height + self.oy <= row_max * 32
        if (@frames % 8) < 2
          @flecheHaut.y -= 1 if @flecheHaut.visible
          @flecheBas.y += 1 if @flecheBas.visible
        elsif (@frames % 8) < 6
          @flecheHaut.y += 1 if @flecheHaut.visible
          @flecheBas.y -= 1 if @flecheBas.visible
        else
          @flecheHaut.y -= 1 if @flecheHaut.visible
          @flecheBas.y += 1 if @flecheBas.visible
        end
        @frames += 1
      end
     
      def length
        return @commands.length
      end
     
      def commandSelected
        return @values[@index]
      end
     
      def replaceCommands(*items)
        valeur = commandSelected
        @values = items
        @commands = affichage
        cw = columnWidth
        @row_max = (@maxHeight / 32) - 1
        @column_max = [@maxWidth / cw, (length / @row_max) + (length % @row_max == 0 ? 0 : 1)].min
        @item_max = length
       
        Graphics.freeze
        if @values.include?(valeur)
          @index = @values.index(valeur)
        else
          @index = 0
        end
        if (length / @column_max) * 32 > self.contents.height
          h = ((length / @column_max) + (length % @column_max == 0 ? 0 : 1) * 5) * 32
          self.contents = Bitmap.new(self.contents.width, h)
          self.contents.font.name = $fontface
          self.contents.font.size = $fontsize
        end
       
        positionnement
        refresh
        Graphics.transition(1)
      end
     
      def affichage
        commands = []
        for value in @values
          commands.push("#{value.split('_')[1]}")
        end
        return commands
      end
     
      def dispose
        return if disposed?
        @flecheHaut.dispose
        @flecheBas.dispose
        super
      end
     
      def refresh
        self.contents.clear
        for i in 0... @item_max
          draw_item(i, (@values[i] == Player.monCode ? disabled_color : normal_color))
        end
      end
    end

    Au début du script Scene_Echanges, vous avez ca :
    Code:
      # L'adresse complète vers le fichier index.php sans le http://
      URL = "localhost/echanges/index.php"

    Indiquez entre les guillemets l'adresse complète (sans le http:// au début) vers le fichier index.php que vous avez mis sur votre serveur tout à l'heure.
    Ensuite, la valeur du FRAME_TIME_OUT sert à déterminer le nombre de frames qui seront affichées en attendant l'autre partie.
    Enfin, téléchargez cette archive qui contient les ressources graphiques et audio utilisées par ce script, puis dézippez le dans le dossier de votre projet.
    Voici la liste des fichiers contenus dans l'archive ZIP :
    • Audio/
      • BGM/
        • PkmRS-Evolving.mid
            Musique de l'animation d'échange
        • PkmRS-MtChimney.mid
            Musique de fond de la scène
      • ME/
        • Caughtjingle.mid
            Son de fin de l'animation d'échange
      • SE/
        • Pokemove.WAV
            Son utilisé dans l'animation d'échange

    • Graphics/
      • Pictures/
        • echange_barre.png
            Barre de progression
        • echange_fond.png
            Fond de la scène
        • echange_interface1-1.png
        • echange_interface1-2.png
        • echange_interface1-3.png
        • echange_interface2.png
        • echange_interface3.png
        • echange_interface4.png
            Eléments de l'animation d'échange
        • fleche_bas.png
        • fleche_haut.png
            Flèches utilisées pour marquer le défilement dans la liste des connectés si elle est trop longue.
        • messagedummy.png
            Fond de message
        • Persian_00.png
        • Persian_01.png
        • Persian_02.png
        • Persian_03.png
        • Persian_04.png
        • Persian_05.png
        • Persian_06.png
        • Persian_07.png
        • Persian_08.png
        • Persian_09.png
        • Persian_10.png
        • Persian_11.png
            Les 12 frames de l'animation d'attente

    Si certaines de vos ressources portent déjà ce nom là, à fortiori si vous les avez personnalisées, renommez les avant de décompresser l'archive, vous éviterez de les remplacer.


Et voilà, vous avez fini l'installation de ce système ! Vous pouvez souffler maintenant ! ^^

    III) Utilisation :

Après une installation assez longue, je suis au regret de vous annoncer que l'utilisation de ce système est on ne peut plus complexe... Il faut créer un évènement, et y glisser cette insertion de scripts :
Code:
echangesTempsReel


Ensuite, réchauffez, servez, puis testez ^^

    IV) LMDLF (Le mot de la fin) :

J'ai fait divers tests (j'ai testé un maximum de situations, une majorité lors de l'élaboration du système avec des bêtatesteurs qui ont bien volontiers accepté de sacrifier de leur temps, puis je l'ai fini ces jours ci en le testant seul sur deux ordinateurs) et le système est fonctionnel. N'hésitez pas à le tester et à me signaler d'éventuels effets de bord.

    V) Nombreux crédits - par ordre alphabétique - :

Tout d'abord, je remercie ceux qui ont contribué à la mise en place de ce système (y compris en perdant un peu de leur temps en testant ce système) :
  • Disscat, pour l'animation d'échange ainsi que l'animation d'attente ;
  • Samyh, pour le back de la scène d'échange ;
  • Yuri, pour les classes Socket et Web_File qui permettent de contacter le serveur PHP.


Je remercie également les testeurs qui ont également bien aidé à l'élaboration du système d'échanges en temps réel :
  • Angi-Mk ;
  • Emeraude ;
  • Palbolsky ;
  • Spiky.
Les membres suivants remercient Sphinx pour ce message :
Disccat (13/01/12), Silver (16/06/12), FL0RENT (30/11/12)


Dernière édition par Sphinx le Dim 8 Jan - 21:32 (2012); édité 4 fois
Revenir en haut
Publicité






MessagePosté le: Mer 24 Aoû - 17:25 (2011)    Sujet du message: Publicité

PublicitéSupprimer les publicités ?
Revenir en haut
Polokus
Membre


Inscrit le: 04 Déc 2008
Messages: 138
Localisation: belgique

MessagePosté le: Mer 24 Aoû - 23:16 (2011)    Sujet du message: Echanges en temps réel v2.1

Bonjour sphinx voici mon bug ^^'

Code:

---------- Erreur de script : Interpreter Bis ----------
----- Type
NameError

----- Message
(eval):1:in `command_355'undefined local variable or method `echanges_temps_reel' for #<Interpreter:0x9ebf888>

----- Position dans Interpreter Bis
Ligne 445

----- Backtrace
Script : Interpreter Bis | Ligne : 445 | Méthode : in `command_355'
Script : Interpreter 2 | Ligne : 215 | Méthode : in `eval'
Script : Interpreter Bis | Ligne : 445 | Méthode : in `command_355'
Script : Interpreter 2 | Ligne : 215 | Méthode : in `execute_command'
Script : Interpreter 1 | Ligne : 199 | Méthode : in `update'
Script : Interpreter 1 | Ligne : 113 | Méthode : in `loop'
Script : Interpreter 1 | Ligne : 204 | Méthode : in `update'
Script : Interpreter 1 | Ligne : 130 | Méthode : in `update'
Script : Interpreter 1 | Ligne : 113 | Méthode : in `loop'
Script : Interpreter 1 | Ligne : 204 | Méthode : in `update'
Script : Scene_Map | Ligne : 51 | Méthode : in `alias_update'
Script : Scene_Map | Ligne : 48 | Méthode : in `loop'
Script : Scene_Map | Ligne : 67 | Méthode : in `alias_update'
Script : MAPPANEL | Ligne : 90 | Méthode : in `old_update'
Script : TempsJourNuit | Ligne : 248 | Méthode : in `update_passminimap'
Script : Minimap | Ligne : 44 | Méthode : in `update'
Script : Scene_Map | Ligne : 25 | Méthode : in `old_main'
Script : Scene_Map | Ligne : 19 | Méthode : in `loop'
Script : Scene_Map | Ligne : 30 | Méthode : in `old_main'
Script : TempsJourNuit | Ligne : 237 | Méthode : in `main_passminimap'
Script : Minimap | Ligne : 31 | Méthode : in `main'
Script : Main | Ligne : 50


voici un screen :



Merci de m'aidez :p bonne soirée Imbécile heureux
Revenir en haut
Pαlвσlѕку
Administrateur
Administrateur


Inscrit le: 17 Aoû 2008
Messages: 5 982
Masculin

MessagePosté le: Mer 24 Aoû - 23:38 (2011)    Sujet du message: Echanges en temps réel v2.1

Sphinx, ça ne serait pas plutôt :

Code:
echangesTempsReel

Non ?
Revenir en haut
Skype
Polokus
Membre


Inscrit le: 04 Déc 2008
Messages: 138
Localisation: belgique

MessagePosté le: Mer 24 Aoû - 23:55 (2011)    Sujet du message: Echanges en temps réel v2.1

oui sa marche Imbécile heureux merci palbolsky Imbécile heureux sauve une autre erreur ^^' :

Code:


wf = Web_File.new(URL, {"mode" => "connect", "monCode" => Player.monCode})



A cette ligne si du script Scene_echange

Et voici le log :
Code:

---------- Erreur de script : Scene_Echange ----------
----- Type
NameError

----- Message
uninitialized constant POKEMON_S::Select_Player::URL

----- Position dans Scene_Echange
Ligne 792

----- Backtrace
Script : Scene_Echange | Ligne : 792 | Méthode : in `listePseudos'
Script : Scene_Echange | Ligne : 754 | Méthode : in `initialize'
Script : Scene_Echange | Ligne : 57 | Méthode : in `new'
Script : Scene_Echange | Ligne : 57 | Méthode : in `main'
Script : Main | Ligne : 50


Merci d'avance Imbécile heureux
Revenir en haut
Sphinx
Scribe
Scribe


Inscrit le: 07 Jan 2008
Messages: 9 736
Localisation: Quelque part, dans le monde... Ou peut être sur une autre planète...
ID Steam: FaQuinator

MessagePosté le: Jeu 25 Aoû - 13:01 (2011)    Sujet du message: Echanges en temps réel v2.1

Ah ? Bizarre :!

Essaies de mettre POKEMON_S:: devant URL, on sait jamais

Pour le echangesTempsReel, je confirme que c'est bien la bonne commande ^^" J'ai corrigé le 1° post
Revenir en haut
Polokus
Membre


Inscrit le: 04 Déc 2008
Messages: 138
Localisation: belgique

MessagePosté le: Jeu 25 Aoû - 14:03 (2011)    Sujet du message: Echanges en temps réel v2.1

bonjour sphinx !

Dsl toujours la même erreur même en mettant "POKEMON_S::" devant URL :(
Revenir en haut
Sphinx
Scribe
Scribe


Inscrit le: 07 Jan 2008
Messages: 9 736
Localisation: Quelque part, dans le monde... Ou peut être sur une autre planète...
ID Steam: FaQuinator

MessagePosté le: Jeu 25 Aoû - 14:08 (2011)    Sujet du message: Echanges en temps réel v2.1

Au début du script, tu dois avoir quelque chose du style :
Code:
URL = "adresse.du/site"


Tu as quoi, toi ?
Revenir en haut
Polokus
Membre


Inscrit le: 04 Déc 2008
Messages: 138
Localisation: belgique

MessagePosté le: Jeu 25 Aoû - 14:12 (2011)    Sujet du message: Echanges en temps réel v2.1

Moi j'ai juste ceci :

DIRNAME = "C:\Users\Monnom\Desktop\PSP5g+ Advanced\Echanges\index.php"

Et après commence le script
Revenir en haut
Sphinx
Scribe
Scribe


Inscrit le: 07 Jan 2008
Messages: 9 736
Localisation: Quelque part, dans le monde... Ou peut être sur une autre planète...
ID Steam: FaQuinator

MessagePosté le: Jeu 25 Aoû - 14:13 (2011)    Sujet du message: Echanges en temps réel v2.1

Arf, c'est ca ton problème ^^'

Remplace le script Scene_Echanges par celui qui est dans ce topic Clin d'œil foireux J'ai changé pas mal de choses
Revenir en haut
Polokus
Membre


Inscrit le: 04 Déc 2008
Messages: 138
Localisation: belgique

MessagePosté le: Jeu 25 Aoû - 14:16 (2011)    Sujet du message: Echanges en temps réel v2.1

Voila j'ai réinstallez tout et tout fonctionne sauve 1 chose que je ne comprend pas bien si dans URL = adresse jusqu'au fichier index.php

on met ou l'adresse de notre hebergeur ?

on héberge Index.php?

xD parce que il me dit que mon rgss player n'est peut être pas autoriser a allez sur le net alors que oui ^^'

merci d'avance
Revenir en haut
Sphinx
Scribe
Scribe


Inscrit le: 07 Jan 2008
Messages: 9 736
Localisation: Quelque part, dans le monde... Ou peut être sur une autre planète...
ID Steam: FaQuinator

MessagePosté le: Jeu 25 Aoû - 14:36 (2011)    Sujet du message: Echanges en temps réel v2.1

Clin d'œil foireux En fait, URL remplace HOSTNAME et DIRNAME

En gros, si tu avais :

HOSTNAME = "monhost.com"
DIRNAME = "/echanges/index.php"

alors tu devras mettre :

URL = "monhost.com/echanges/index.php"

Clin d'œil foireux
Revenir en haut
Polokus
Membre


Inscrit le: 04 Déc 2008
Messages: 138
Localisation: belgique

MessagePosté le: Jeu 25 Aoû - 14:42 (2011)    Sujet du message: Echanges en temps réel v2.1

ha oki merci beaucoup Imbécile heureux je le rajoute a PSP5G+ Advanced Imbécile heureux
Revenir en haut
Giratinaprimal
Membre


Inscrit le: 08 Oct 2010
Messages: 69
Renégat
Localisation: ???
Masculin

MessagePosté le: Jeu 1 Sep - 14:45 (2011)    Sujet du message: Echanges en temps réel v2.1

Le système de Tradegroup est-il toujours actif dans ce système ?
D'après le manuel :


"Ce nombre, réglable dans le script Config Panel, permet de séparer les jeux qui ne sont pas compatibles. Ainsi, avec le script d'échange PSP, 2 jeux qui n'ont pas le même TRADEGROUP ne pourront pas échanger leurs données. Sauf exception, le TRADEGROUP 0, qui permet de recevoir des Pokémons de n'importe quel TRADEGROUP."


Revenir en haut
Sphinx
Scribe
Scribe


Inscrit le: 07 Jan 2008
Messages: 9 736
Localisation: Quelque part, dans le monde... Ou peut être sur une autre planète...
ID Steam: FaQuinator

MessagePosté le: Jeu 1 Sep - 19:27 (2011)    Sujet du message: Echanges en temps réel v2.1

Imbécile heureux Il est encore actif, mais par contre je crois bien qu'un TRADEGROUP à 0 ne marchera plus comme dans PSP0.7 (j'ai pas pensé à ca en fait... x))
Revenir en haut
Giratinaprimal
Membre


Inscrit le: 08 Oct 2010
Messages: 69
Renégat
Localisation: ???
Masculin

MessagePosté le: Jeu 1 Sep - 20:12 (2011)    Sujet du message: Echanges en temps réel v2.1

Bah, rares seront les projets avec le TRADEGROUP 0, vu les risques d'erreurs de BDD de l'ancien système d'échanges...
Revenir en haut
Contenu Sponsorisé






MessagePosté le: Aujourd’hui à 07:53 (2017)    Sujet du message: Echanges en temps réel v2.1

Revenir en haut
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet    Pokémon Script Project Index du Forum -> Game Making -> Ressources techniques -> Scripts Toutes les heures sont au format GMT + 1 Heure
Aller à la page: 1, 2, 3, 4, 5  >
Page 1 sur 5

 
Sauter vers:  

Index | Creer un forum | Forum gratuit d’entraide | Annuaire des forums gratuits | Signaler une violation | Conditions générales d'utilisation
Powered by phpBB © 2001, 2005 phpBB Group
Thème par Thomas et l'équipe de la refonte PSP 2012 (version 1.0)
Traduction par : phpBB-fr.com