Warband Modding: Eventos servidor y cliente

    Comparte

    Prodigy
    Caballero de la Orden
    Caballero de la Orden

    : : Just in case they come creepy
    Mensajes : 2519
    Edad : 18
    Facción : AFK Army

    Warband Modding: Eventos servidor y cliente

    Mensaje por Prodigy el Mar Dic 03, 2013 3:38 pm

    tutorial por Yoshiboy,Post de TaleWorlds

    --------------
    Así que recientemente he tenido un buen número de MP's preguntando sobre problemas diversos de personas han tenido con modding partida de guerra - sobre todo que ver con la idea de conseguir algo para sincronizar entre el servidor de todos los clientes. Así que lo que pensé que haría es escribir un tutorial de pasar por todo esto, así que espero que la gente consigue la idea. Es bastante simple, proporcionando que sepas lo que estás buscando. Así que aquí vamos.
    ---------------

    Parte 1 - Cómo pensar en modding multijugador

    Ok, así que el primer problema que nos encontramos con este tipo de cosas en Hunt era que los sonidos de armas sólo jugaría en el equipo del jugador que les disparó. Por supuesto, esto no era realmente el fin del mundo - pero era un dolor - así que busqué en cómo podíamos hacer que se sincronizan. En este tutorial voy a estar pasando por cómo agregar nuevos eventos de servidor y cliente, en este caso para que nuestros sonidos de armas (o cualquier otro sonido) para sincronizar entre los jugadores. Así que el ejemplo de ejecución será este evento arma - pero debería ser aplicable a básicamente todos los otros eventos que necesitará y problemas del mismo tipo.

    Lo que hice fue tomar primero un vistazo a todos los nuevos comandos multijugador. Tenemos algunos otros que se parecen a esto:
    Código:
    # multiplayer
    multiplayer_send_message_to_server  = 388 # (multiplayer_send_int_to_server, <message_type>),
    multiplayer_send_int_to_server      = 389 # (multiplayer_send_int_to_server, <message_type>, <value>),
    multiplayer_send_2_int_to_server    = 390 # (multiplayer_send_2_int_to_server, <message_type>, <value>, <value>),
    multiplayer_send_3_int_to_server    = 391 # (multiplayer_send_3_int_to_server, <message_type>, <value>, <value>, <value>),
    multiplayer_send_4_int_to_server    = 392 # (multiplayer_send_4_int_to_server, <message_type>, <value>, <value>, <value>, <value>),
    multiplayer_send_string_to_server    = 393 # (multiplayer_send_string_to_server, <message_type>, <string_id>),
    multiplayer_send_message_to_player  = 394 # (multiplayer_send_message_to_player, <player_id>, <message_type>),
    multiplayer_send_int_to_player      = 395 # (multiplayer_send_int_to_player, <player_id>, <message_type>, <value>),
    multiplayer_send_2_int_to_player    = 396 # (multiplayer_send_2_int_to_player, <player_id>, <message_type>, <value>, <value>),
    multiplayer_send_3_int_to_player    = 397 # (multiplayer_send_3_int_to_player, <player_id>, <message_type>, <value>, <value>, <value>),
    multiplayer_send_4_int_to_player    = 398 # (multiplayer_send_4_int_to_player, <player_id>, <message_type>, <value>, <value>, <value>, <value>),
    multiplayer_send_string_to_player    = 399 # (multiplayer_send_string_to_player, <player_id>, <message_type>, <string_id>),
    Todos ellos parecen estar a punto de enviar las cosas entre los jugadores y el servidor. Más sobre esto más adelante.

    También tenemos esta otra:
    Código:
    multiplayer_is_server                = 417 # (multiplayer_is_server),
    Lo cual es algo condicional en " probar" los bloques que sólo permite al servidor para ejecutar los comandos siguientes que (también se puede negar con neg | para que sea sólo cliente)

    Así que , básicamente, el servidor y el cliente , tanto corren todo el módulo en su totalidad con la excepción del servidor que ejecuta estos bloques " multiplayer_is_server " y el cliente sólo ejecuta las negadas . La mayoría de las veces esto realmente funciona muy bien para nosotros - junto con todo el material codificado esto significa casi todo lo que ya está sincronizado . Sólo nos encontramos con problemas con un par de cosas . Como cuando el jugador o el servidor genera un número aleatorio - éstos serán diferentes. O cuando el jugador hace ciertas cosas como ejecutar el código después de disparar un arma o el código después de la interacción con un puntal escena - esto es algo que el servidor no hace un seguimiento ni tomó en cuenta.

    Así que cuando usted está pensando en modding multijugador , recuerde lo siguiente:

    * Cada cliente y el servidor se ejecutan todo el módulo en su totalidad con la excepción del servidor que ejecuta " multiplayer_is_server " bloques y el cliente que ejecuta los negados .
    * El servidor ve todo el mundo como cualquier otro " agente" o , con mayor profundidad , un "jugador " . No realizar un seguimiento de lo que está sucediendo en su extremo .
    * Lo mismo va para el cliente - todo el mundo es más que otro " jugador " y todo lo que trata de hacer es ponerlos en la posición correcta , haciendo lo correcto .

    Parte 2 - La configuracion de nuestra arma

    Así que teniendo un rápido vistazo a el código de la pistola:
    Código:
    ["flintlock_pistol", "Flintlock Pistol", [("flintlock_pistol",0)], itp_type_pistol |itp_merchandise|itp_primary ,itcf_shoot_pistol|itcf_reload_pistol, 230 , weight(1.5)|difficulty(0)|spd_rtng(38) | shoot_speed(160) | thrust_damage(45 ,pierce)|max_ammo(1)|accuracy(65),imodbits_none,
     [(ti_on_weapon_attack, [(play_sound,"snd_pistol_shot"),(position_move_x, pos1,27),(position_move_y, pos1,36),(particle_system_burst, "psys_pistol_smoke", pos1, 15)])]],
    Es bastante obvio lo que está mal. El (play_sound "snd_pistol_shot") sólo tiene un ruido en el cliente que lo utiliza, y no envía datos a todos los demás.

    (Nota: la materia de partículas parece que ya ha hardcoded eventos, así que no tenemos que sincronizar esto.)

    La solución es usar uno de los nuevos comandos de varios jugadores, para enviar los datos al servidor, diciendo a todos que nos hemos disparado el arma, por lo que a continuación, puede transmitir esto a todos los otros jugadores. Pero todos esos comandos tienen un parámetro . Usted podría preguntarse por qué es esto. Bueno, es el tipo de evento - de los cuales todos los actuales se muestran en header_common, y tenemos que crear nuestro propio antes de que podamos utilizar el comando. Estamos agregando una nueva "CLIENT_EVENT", porque es el cliente que envía el mensaje al servidor. Vamos a llamar a nuestro "multiplayer_event_sound_made_by_player"

    Código:
    ...
    multiplayer_event_admin_set_friendly_fire_damage_self_ratio  = 40
    multiplayer_event_admin_set_friendly_fire_damage_friend_ratio = 41
    multiplayer_event_admin_set_allow_player_banners              = 42
    multiplayer_event_admin_set_force_default_armor              = 43
    multiplayer_event_admin_set_anti_cheat                        = 44

    # NEW EVENTS

    multiplayer_event_sound_made_by_player = 45

    ...
    (Nota: En las versiones más nuevas de M & B, se han añadido más eventos, así que los números constantes anteriores podrían tener que ser cambiado Sólo asegúrese de que no hay dos números de evento que se superponen y que no se va por encima de 128, porque este es el codificado. límite. Si necesita más eventos, considere el uso de sub-eventos usando siempre un número de evento, pero luego de pasar un parámetro adicional para diferenciar entre lo que quieres hacer.)

    Ahora cambiar el código de la pistola para que utilice el evento es bastante simple. Quitamos el comando "play_sound" y reemplazamos con nuestro nuevo mensaje al servidor. Idealmente vamos a querer el servidor para retransmitir este evento de sonido de nuevo a todos los jugadores - incluyendo el que hizo el sonido.

    Código:
    ["flintlock_pistol", "Flintlock Pistol", [("flintlock_pistol",0)], itp_type_pistol |itp_merchandise|itp_primary ,itcf_shoot_pistol|itcf_reload_pistol, 230 , weight(1.5)|difficulty(0)|spd_rtng(38) | shoot_speed(160) | thrust_damage(45 ,pierce)|max_ammo(1)|accuracy(65),imodbits_none,
     [(ti_on_weapon_attack, [(multiplayer_send_int_to_server,multiplayer_event_sound_made_by_player,"snd_pistol_shot"),(position_move_x, pos1,27),(position_move_y, pos1,36),(particle_system_burst, "psys_pistol_smoke", pos1, 15)])]],

    Parte 3 - Decirle al servidor qué hacer


    Así que ahora tenemos el arma que envía un mensaje al servidor, pero el servidor no sabe qué hacer cuando recibe este mensaje, por lo que tenemos que añadir algo de código para eso. Abre module_scripts y la búsqueda de este guión "game_receive_network_message".

    Este es un script muy importante. Básicamente se trata de la secuencia de comandos que se llama cada vez que se utiliza cualquiera de los nuevos comandos "multiplayer_send_X_to_Y", y los diversos parámetros de script se corresponden con los datos adicionales que se envían por el comando. Así que aquí, queremos añadir un poco de código que se ejecuta cuando se recoge en nuestros mensajes. Un poco confusamente queremos añadir nuestro código en la sección marcada con "eventos de servidor", ya que es el servidor que ejecuta nuestras cosas. Vamos a añadir nuestro código a la derecha en el final para desplazarse hasta justo por encima de donde tenemos el "Cliente EVENTOS" en un bloque de comentarios y lo añadiremos algo de código:

    Código:
    ...
              (assign, "$g_multiplayer_force_default_armor", ":value"),
            (try_end),
          (else_try),
        
         # NEW EVENTS ADDED
        
         (eq,":event_type", multiplayer_event_sound_made_by_player),
         (neq,":player_no",0),
         (store_script_param, ":sound", 3),
        
              (get_max_players, ":num_players"),
              (try_for_range, ":cur_player", 0, ":num_players"),
                (player_is_active,":cur_player"),
                (multiplayer_send_2_int_to_player, ":cur_player", multiplayer_event_sound_at_player, ":sound",":player_no"),
              (try_end),
        
         (else_try),
        
         # END NEW EVENTS ADDED
        
            ###############
            #CLIENT EVENTS#
            ###############
            (neq, multiplayer_is_server),
            (try_begin),     
    ...
    Ok, así que tenemos un par de cosas que suceden aquí. En primer lugar se dará cuenta de un nuevo evento que he colé en - "multiplayer_event_sound_at_player". Vamos a tener que agregar esto a header_common, bajo la sección de eventos de servidor (como lo es el servidor que lo utiliza)

    Código:
    ...
    multiplayer_event_return_anti_cheat                          = 104

    # NEW SERVER EVENTS

    multiplayer_event_sound_at_player = 105
    ...
    Este es el caso de que los clientes recojan, para decirles que algún jugador (": player_no") ha hecho un sonido (":sound"). ": player_no" es una variable agarró justo al principio de la secuencia de comandos, y se corresponde con el jugador que envía el mensaje de evento al servidor en el primer lugar. ": El sonido" es sólo la variable de sonido que fue enviado por el jugador - agarramos esto desde los parámetros de script.

    Entonces, finalmente, tenemos una oportunidad para el bloque de rango - que un bucle sobre todos los jugadores, y les envía este mensaje. Y ya hemos terminado con el servidor.

    Parte 4 - Contar los clientes qué hacer

    Obtención de los clientes a hacer lo correcto es en realidad bastante similar. Es posible que haya visto el bloque macizo comentarios etiquetada "CLIENTES EVENTOS" y esto es exactamente donde vamos a añadir nuestro código para la captura de este nuevo mensaje del servidor acaba de enviar. Desplácese hacia abajo hasta el fondo de este bloque de "eventos de cliente" y añadiremos nuestro nuevo código.

    Código:
    ...
                (store_add, "$g_my_spawn_count", "$g_my_spawn_count", ":value"),
              (else_try),
                (assign, "$g_my_spawn_count", ":value"),     
              (try_end),
          
          # NEW CLIENT EVENTS
          
          (else_try),
             (eq, ":event_type", multiplayer_event_sound_at_player),
             (store_script_param, ":sound", 3),
             (store_script_param, ":player", 4),
          
             (player_get_agent_id,":agent",":player"),
             
             (try_begin),
             (neq,":agent",-1),
                (display_message,"@BANG!"), # This is just a debug message, it isn't essential.
                (agent_play_sound,":agent",":sound"),
             (end_try),
             
          # END NEW CLIENT EVENTS 
           
            (try_end),
        ]),
    ...
    Así que esto es todo foward bastante recta. Ponemos a prueba para ver si es nuestro nuevo evento, si es así nos agarramos el parámetro para el cual se hizo el sonido y el jugador que hizo el sonido. Entonces nos encontramos con el agente que los usos de los jugadores y conseguimos hacer el sonido. También he añadido un mensaje de depuración para la prueba. Para detener algunos errores también hay que probar para un agente nulo.

    Parte 5 - Ha terminado

    Y eso es todo. Lo creas o no haya terminado. Compilar el código, cargue el servidor que ejecuta su nuevo mod, conseguir un par de jugadores de allí y disparar a distancia.


    Por último, es probablemente la pena señalar la diferencia entre servidores dedicados y juegos organizados y cómo esto afecta a su código. La principal diferencia es que en los juegos organizados , jugador número 0 también es un jugador que juega el juego (y , como tal, tendrá que ser enviado eventos de sonido y similares ), donde al igual que con un servidor dedicado, jugador número 0 es siempre el servidor. Esto le puede conseguir en diferentes bits de problemas si no tienes cuidado y creo que se han introducido algunas otras peculiaridades en las versiones recientes también que no estoy familiarizado. La manera de ver si el juego se ejecuta como dedicado o acogido es utilizar el comando " multiplayer_is_dedicated_server " .

    Mucha gente ha estado diciendo que lo hicieron este tutorial exactamente y que no funcionó (es decir, no jugó ningún sonido ) . Me encantaría ayudarte, pero doy cuenta que no puedo leer la mente. A menos que usted me da algo más de información , entonces no tengo más idea de lo que sobre la forma de conseguir que funcione . Lo que debe hacer en este momento es tratar de añadir en algunos mensajes de depuración utilizando " Mostrar_Mensaje " para ver qué partes del código están siendo ejecutados y los que no lo son. Realmente cualquier información ayudará a que te diga que las cosas pueden ir mal .

    Si alguien encuentra algún error en el tutorial o tiene cualquier problema , por favor, dicen. Hice probarlo en el juego y que estaba siendo un poco divertido (aunque el código es exactamente el mismo que para la caza así que no estoy seguro de por qué ) .


    _________________
    ''Un hombre bueno puede ser idiota, pero un hombre malo tiene que ser inteligente''-Leonardo Davinci

    "Intuyo que el placer que da gobernar es muy grande, puesto que todos quieren lograrlo".- Voltaire


    Never gonna give up

      Fecha y hora actual: Sáb Dic 03, 2016 2:39 pm