Skip to content
DizzasTeR edited this page Nov 17, 2020 · 3 revisions
--[[
- Vice City Multiplayer 0.4 Blank Server (by Seby) for 64bit Windows.
- You can use it to script your own server. Here you can find all events developed.
-
- Rewritten in Lua by DMWarrior.
- Fixed and updated (DizzasTeR)
-
- VC:MP Official: www.vc-mp.org
- Forum: forum.vc-mp.org
- Wiki: wiki.vc-mp.org
--]]

 ----
 -- Criando uma conexão entre scripts do cliente e do servidor.
 --
 -- Isto é usado para estabelecer uma conexão entre os scripts do cliente e do
 -- servidor. O byte definido aqui representa o cabeçalho (header), e deve ser o
 -- mesmo em server-side e client-side.
 local StreamType = {
    ServerName = 0x01
  }
 
 -- ======================= S E R V E R   E V E N T S ==========================
 
 ----
 -- @event onServerInit
 --
 -- Evento acionado ao inicializar o servidor.
 --
 function onServerInit()
   -- Nome e senha do servidor:
   local name = Server.getName()
   local password = Server.getPassword()
 
   print("Servidor inicializado.")
   print("[Nome: \"" .. name .. "\"] [Senha: \"" .. password .. "\"]")
 end
 
 ----
 -- @event onServerShutdown
 --
 -- Evento acionado ao encerrar o servidor.
 --
 function onServerShutdown()
   print("Servidor fechado.")
 end
 
 -- ======================= P L A Y E R   E V E N T S ==========================
 
 ----
 -- @event onPlayerConnect
 -- Evento acionado quando um jogador entra no servidor.
 --
 -- @param {Player} player Jogador.
 --
 function onPlayerConnect(player)
   -- ...
 end
 
 ----
 -- @event onPlayerDisconnect
 -- Evento acionado quando um jogador sai do servidor.
 --
 -- @param {Player} player Jogador.
 -- @param {number} reasonID ID do motivo da saída.
 --
 --        Motivos de saída (listados em "DisconnectReason"):
 --        * timeout
 --        * quit
 --        * kick
 --        * ban
 --        * kickBan
 --        * crash
 --        * ac
 --
 function onPlayerDisconnect(player, reasonID)
   -- ...
 end
 
 ----
 -- @event onPlayerRequestClass
 -- Evento acionado quando um jogador requisita uma classe.
 --
 -- @param {Player} player Jogador.
 -- @param {number} classID ID da classe escolhida.
 --
 -- @return {boolean}
 --
 function onPlayerRequestClass(player, classID)
    return true
 end
 
 ----
 -- @event onPlayerRequestSpawn
 -- Evento acionado quando um jogador requisita o spawn no jogo.
 --
 -- @param {Player} player Jogador.
 --
 -- @return {boolean}
 --
 function onPlayerRequestSpawn(player)
   return true
 end
 
 ----
 -- @event onPlayerSpawn
 -- Evento acionado quando um jogador spawna no jogo.
 --
 -- @param {Player} player Jogador.
 --
 function onPlayerSpawn(player)
   -- ...
 end
 
 ----
 -- @event onPlayerWasted
 --
 -- Evento acionado quando um jogador morre.
 --
 -- @param {Player} player Jogador.
 -- @param {number} reasonID ID da causa da morte.
 --
 function onPlayerWasted(player, reasonID)
   -- ...
 end
 
 ----
 -- @event onPlayerKill
 -- Evento acionado quando um jogador é assassinado.
 --
 -- @param {Player} killer Assassino.
 -- @param {Player} player Jogador.
 -- @param {number} reasonID ID da causa da morte.
 -- @param {number} bodyPartID ID da parte do corpo atingida.
 --
 --        Partes do corpo (listadas em "BodyPart"):
 --        * body
 --        * torso
 --        * leftArm
 --        * rightArm
 --        * leftLeg
 --        * rightLeg
 --        * head
 --        * inVehicle
 --
 function onPlayerKill(killer, player, reasonID, bodyPartID)
   -- ...
   if killer and killer.team == player.team then
    Event.trigger("onPlayerTeamKill", killer, player, reasonID, bodyPartID)
   end
 end

 ----
 -- @event onPlayerTeamKill
 -- Evento acionado quando um jogador é assassinado.
 --
 -- @param {Player} killer Assassino.
 -- @param {Player} player Jogador.
 -- @param {number} reasonID ID da causa da morte.
 -- @param {number} bodyPartID ID da parte do corpo atingida.
 --
 --        Partes do corpo (listadas em "BodyPart"):
 --        * body
 --        * torso
 --        * leftArm
 --        * rightArm
 --        * leftLeg
 --        * rightLeg
 --        * head
 --        * inVehicle
 --
 function onPlayerTeamKill(killer, player, reasonID, bodyPartID)
    -- ...
 end
 
 ----
 -- @event onPlayerMessage
 -- Evento acionado quando um jogador envia uma mensagem no chat.
 --
 -- @param {Player} player Jogador.
 -- @param {string} text Mensagem enviada.
 --
 -- @return {boolean}
 --
 function onPlayerMessage(player, text)
   print(player.name .. ": " .. text)
   return true
 end
 
 ----
 -- @event onPlayerCommand
 -- Evento acionado quando um jogador insere um comando no chat.
 --
 -- @param {Player} player Jogador.
 -- @param {string} command Comando.
 -- @param {string[]} args Parâmetros do comando.
 --
 -- @return {boolean}
 --
 function onPlayerCommand(player, command, args)
   ----
   -- @command /hello
   -- Responde o jogador com uma mensagem.
   --
  if (command == "hello") then
     player:msg("Oh! Hello, " .. player.name .. "!")
 
   ----
   -- @command /[...]
   -- Erro que ocorre ao inserir um comando inválido.
   else
     player:msg("Invalid command.")
   end
 
   return true
 end
 
 ----
 -- @event onPlayerPM
 -- Evento acionado quando um jogador envia uma MP (Mensagem Privada) para outro
 -- jogador.
 --
 -- @param {Player} player Jogador (remetente).
 -- @param {Player} playerTo Jogador (destinatário).
 -- @param {string} message Mensagem enviada.
 --
 -- @return {number}
 --
 function onPlayerPM(player, playerTo, message)
   return true
 end
 
 ----
 -- @event onPlayerBeginTyping
 -- Evento acionado quando um jogador começa a escrever uma mensagem.
 --
 -- @param {Player} player Jogador.
 --
 function onPlayerBeginTyping(player)
   -- ...
 end
 
 ----
 -- @event onPlayerFinishTyping
 -- Evento acionado quando um jogador termina de escrever uma mensagem.
 --
 -- @param {Player} player Jogador.
 --
 function onPlayerFinishTyping(player)
   -- ...
 end
 
 ----
 -- @event onPlayerSpectate
 -- Evento acionado quando um jogador está assistindo a uma partida, em modo
 -- espectador.
 --
 -- @param {Player} player Jogador.
 -- @param {Player} target Foco do espectador.
 --
 function onPlayerSpectate(player, target)
   -- ...
 end
 
 ----
 -- @event onPlayerCrashReport
 -- Evento acionado quando ocorre crash em um dos clientes.
 --
 -- @param {Player} player Jogador.
 -- @param {string} report Dados de travamento.
 --
 function onPlayerCrashReport(player, report)
   -- ...
 end
 
 ----
 -- @event onPlayerAwayChange
 -- Evento acionado quando o estado de um jogador muda após se ausentar.
 --
 -- @param {Player} player Jogador.
 -- @param {boolean} isAway Status do jogador.
 --
 function onPlayerAwayChange(player, isAway)
   -- ...
 end
 
 ----
 -- @event onPlayerNameChange
 -- Evento acionado quando um jogador altera seu nome.
 --
 -- @param {Player} player Jogador.
 -- @param {string} oldName Nome anterior.
 -- @param {string} newName Nome atual.
 --
 function onPlayerNameChange(player, oldName, newName)
   -- ...
 end
 
 ----
 -- @event onPlayerActionChange
 -- Evento acionado quando a ação de um jogador muda.
 --
 -- @param {Player} player Jogador.
 -- @param {number} oldAction Ação anterior.
 -- @param {number} newAction Ação atual.
 --
 function onPlayerActionChange(player, oldAction, newAction)
   -- ...
 end
 
 ----
 -- @event onPlayerStateChange
 -- Evento acionado quando o estado de um jogador muda.
 --
 -- @param {Player} player Jogador.
 -- @param {number} oldState Estado anterior.
 -- @param {number} newState Estado atual.
 --
 function onPlayerStateChange(player, oldState, newState)
   -- ...
 end
 
 ----
 -- @event onPlayerFireChange
 -- Evento acionado quando o estado de incêndio de um jogador muda (isto é, se
 -- ele está pegando fogo ou não).
 --
 -- @param {Player} player Jogador.
 -- @param {boolean} isOnFire O jogador está pegando fogo agora?
 --
 function onPlayerFireChange(player, isOnFire)
   -- ...
 end
 
 ----
 -- @event onPlayerCrouchChange
 -- Evento acionado quando o estado de postura de um jogador muda (isto é, se
 -- ele está agachado ou não).
 --
 -- @param {Player} player Jogador.
 -- @param {boolean} IsCrouchingNow O jogador está agachado agora?
 --
 function onPlayerCrouchChange(player, IsCrouching)
   -- ...
 end
 
 ----
 -- @event onPlayerGameKeysChange
 -- Evento acionado quando um jogador altera algumas teclas do jogo.
 --
 -- @param {Player} player Jogador.
 -- @param {number} oldKeys Teclas anteriores.
 -- @param {number} newKeys Teclas atuais.
 --
 function onPlayerGameKeysChange(player, oldKeys, newKeys)
   -- ...
 end
 
 ----
 -- @event onPlayerUpdate
 -- Evento de "update" do jogador.
 --
 -- @param {Player} player Jogador.
 -- @param {any} updateType Dados de "update".
 --
 function onPlayerUpdate(player, updateType)
   -- ...
 end
 
 ----
 -- @event onClientData
 -- Evento acionado ao receber dados vindos do cliente.
 --
 -- @param {Player} player Jogador (cliente).
 -- @param {Stream} stream Dados do cliente.
 -- @param {number} size Tamanho dos dados enviados (em bytes).
 --
 function onClientData(player, stream, size)
   -- Recebendo dados do cliente...
   local stream = stream:readByte()
 
   -- Os dados enviados não são nada mais do que um byte, o mesmo definido lá
   -- em cima do script. Ele é usado para indicar que este é o início da
   -- transmissão, ou seja, o "cabeçalho" (header) do que pode estar por vir.
   --
   -- Nesse exemplo, enviaremos o título do servidor de volta para o jogador:
   if (stream == StreamType.ServerName) then
     print("Server received client's request, so it's sending back the server name.")
     -- server received the request of client-side, so it sends back the server name
     sendDataToClient(player, StreamType.ServerName, Server.getName())
   end
 
   print(stream)
 end
 
 -- ====================== V E H I C L E   E V E N T S =========================
 
 ----
 -- @event onVehicleUpdate
 -- Evento de "update" de um veículo.
 --
 -- @param {Vehicle} vehicle Veículo.
 -- @param {any} updateType Dados de "update".
 --
 function onVehicleUpdate(vehicle, updateType)
   -- ...
 end
 
 ----
 -- @event onVehicleExplode
 -- Evento acionado quando um veículo explode.
 --
 -- @param {Vehicle} vehicle Veículo.
 --
 function onVehicleExplode(vehicle)
   -- ...
 end
 
 ----
 -- @event onVehicleRespawn
 -- Evento acionado quando um veículo respawna.
 --
 -- @param {Vehicle} vehicle Veículo.
 --
 function onVehicleRespawn(vehicle)
   -- ...
 end
 
 -- ======================= P I C K U P   E V E N T S ==========================
 
 ----
 -- @event onPickupPickAttempt
 -- Evento acionado quando um pickup é "clamado" por um dos jogadores.
 --
 -- @param {Pickup} pickup Pickup.
 -- @param {Player} player Jogador.
 --
 -- @return {boolean}
 --
 function onPickupPickAttempt(pickup, player)
     return true
 end
 
 ----
 -- @event onPickupPicked
 -- Evento acionado quando um pickup é coletado por um dos jogadores.
 --
 -- @param {Pickup} pickup Pickup.
 -- @param {Player} player Jogador.
 --
 function onPickupPicked(pickup, player)
   -- ...
 end

  ----
 -- @event onPickupRespawn
 -- Evento Description
 --
 -- @param {Pickup} pickup Pickup.
 --
 function onPickupRespawn(pickup)
    -- ...
  end
 
 -- ====================== O B J E C T   E V E N T S ===========================
 
 ----
 -- @event onObjectShot
 -- Evento acionado quando um objeto é alvejado por um dos jogadores.
 --
 -- @param {Object} object Objeto.
 -- @param {Player} player Jogador.
 -- @param {number} weapon ID da arma do jogador.
 --
 function onObjectShot(object, player, weaponID)
   -- ...
 end
 
 ----
 -- @event onObjectTouch
 -- Evento acionado quando um objeto é atingido/colidido por um dos jogadores.
 --
 -- @param {Object} object Objeto.
 -- @param {Player} player Jogador.
 --
 function onObjectTouch(object, player)
   -- ...
 end
 
 -- ================== C H E C K P O I N T   E V E N T S =======================
 
 ----
 -- @event onCheckpointEnter
 -- Evento acionado quando um dos checkpoints é entrado por um dos jogadores.
 --
 -- @param {Checkpoint} checkpoint Checkpoint.
 -- @param {Player} player Jogador.
 --
 function onCheckpointEnter(checkpoint, player)
   -- ...
 end
 
 ----
 -- @event onCheckpointExit
 -- Evento acionado quando um dos checkpoints é saído por um dos jogadores.
 --
 -- @param {Player} player Jogador.
 -- @param {Checkpoint} checkpoint Checkpoint.
 --
 function onCheckpointExit(checkpoint, player)
   -- ...
 end
 
 -- ======================= B I N D   E V E N T S ==============================
 
 ----
 -- @event onPlayerKeyDown
 -- Evento acionado quando um jogador pressiona e/ou mantém uma tecla.
 --
 -- @param {Player} player Jogador.
 -- @param {Bind} bind Tecla.
 --
 function onPlayerKeyDown(player, bind)
   -- ...
 end
 
 ----
 -- @event onPlayerKeyUp
 -- Evento acionado quando um jogador solta uma tecla.
 --
 -- @param {Player} player Jogador.
 -- @param {Bind} bind Tecla.
 --
 function onPlayerKeyUp(player, bind)
   -- ...
 end
 
 -- ============== E N D   OF   O F F I C I A L   E V E N T S ==================
 
 ----
 -- Função utilitária que envia dados do servidor para o cliente.
 --
 -- @param {Player} player Jogador (cliente).
 -- @param {any[]} {...} Parâmetros adicionais...
 --
 function SendDataToClient(player, ...)
   -- Obter lista de parâmetros adicionais e instanciar um stream de dados...
   local arguments = {...}
   local stream = Stream:new()
 
   -- É necessário ter pelo menos um byte para que o envio ocorra. Para reforçar
   -- isto, verificamos se ao menos um parâmetro (além da instância do jogador)
   -- foi passado:
   if (arguments[1] ~= nil) then
 
     -- Variáveis contendo o primeiro byte e o tamanho total dos dados a serem
     -- enviados:
     local byte = arguments[1]
     local len  = #arguments
 
     -- Embora o envio precise de, no mínimo, 1 byte, na verdade o primeiro byte
     -- recebido serve de cabeçalho (header) e não realmente conta como
     -- "conteúdo". Por isso, o mínimo verdadeiro são 2 bytes:
     if (1 > len) then
       print("ToClient: <" .. byte .. "> No params specified.")
 
     -- Se tudo estiver bem, o código de envio será executado a partir daqui...
     else
       arguments[1] = nil -- We don't want to include the byte in our data parsing
       
       -- Começar a escrever dados para streaming. O primeiro byte a ser escrito
       -- será, é claro, o cabeçalho (header):
       stream:writeByte(byte)
 
       -- Percorrer todo o conteúdo passado para o envio. Exceto pelo cabeçalho
       -- (header), o restante pode assumir uma série de valores diferentes.
       --
       -- O tipo deles será comparado no "switch case" abaixo, e as funções
       -- de streaming para cada um deles será chamada de acordo...
       for key, value in ipairs(arguments) do
         if (math.type(value) == "integer") then
           stream:writeNumber(value)
 
         elseif (math.type(value) == "float") then
           stream:writeFloat(value)
 
         elseif (type(value) == "string") then
           stream:writeString(value)
         end
       end
 
       -- Se o jogador estiver instanciado corretamente, os dados serão
       -- enviados diretamente a ele (o cliente):
       if (player ~= nil) then
         stream:sendStream(player)
 
       -- Em qualquer outro caso, infere-se que o jogador não está online e,
       -- portanto, não pode receber dados:
       else
         print("ToClient: <" .. byte .. "> Player is not online.")
       end
 
     end
 
   -- Quando nem o byte de cabeçalho (header) é passado, não há o que fazer.
   -- Para que o servidor enviaria "nada" a alguém?
   else
     print("ToClient: Even the byte wasn't specified...")
   end
 end
 
 -- ===================== E V E N T   B I N D I N G S ==========================
 
 -- Register Non-Traditional Events
    Event.create("onPlayerTeamKill")

 --------
 -- Server events...
 --------
    Event.bind("onServerInit", onServerInit)
    Event.bind("onServerShutdown", onServerShutdown)
 --------
 -- Player events...
 --------
    Event.bind("onPlayerConnect", onPlayerConnect)
    Event.bind("onPlayerDisconnect", onPlayerDisconnect)
    Event.bind("onPlayerRequestClass", onPlayerRequestClass)
    Event.bind("onPlayerRequestSpawn", onPlayerRequestSpawn)
    Event.bind("onPlayerSpawn", onPlayerSpawn)
    Event.bind("onPlayerWasted", onPlayerWasted)
    Event.bind("onPlayerKill", onPlayerKill)
    Event.bind("onPlayerTeamKill", onPlayerTeamKill) -- Can be done manually using onPlayerKill
    Event.bind("onPlayerMessage", onPlayerMessage)
    Event.bind("onPlayerCommand", onPlayerCommand)
    Event.bind("onPlayerPM", onPlayerPM)
    Event.bind("onPlayerBeginTyping", onPlayerBeginTyping)
    Event.bind("onPlayerFinishTyping", onPlayerFinishTyping)
 -- Event.bind("onLoginAttempt", onLoginAttempt) -- N/A
 -- Event.bind("onNameChangeable", onNameChangeable) -- N/A
    Event.bind("onPlayerSpectate", onPlayerSpectate)
    Event.bind("onPlayerCrashReport", onPlayerCrashReport)
 -- Event.bind("onPlayerMove", onPlayerMove) -- Can be done manually using onPlayerUpdate
 -- Event.bind("onPlayerHealthChange", onPlayerHealthChange) -- Can be done manually using onPlayerUpdate
 -- Event.bind("onPlayerArmourChange", onPlayerArmourChange) -- Can be done manually using onPlayerUpdate
 -- Event.bind("onPlayerWeaponChange", onPlayerWeaponChange) -- Can be done manually using onPlayerUpdate
    Event.bind("onPlayerAwayChange", onPlayerAwayChange)
    Event.bind("onPlayerNameChange", onPlayerNameChange)
    Event.bind("onPlayerActionChange", onPlayerActionChange)
    Event.bind("onPlayerStateChange", onPlayerStateChange)
    Event.bind("onPlayerFireChange", onPlayerFireChange)
    Event.bind("onPlayerCrouchChange", onPlayerCrouchChange)
    Event.bind("onPlayerGameKeysChange", onPlayerGameKeysChange)
    Event.bind("onPlayerUpdate", onPlayerUpdate)
 --------
 -- Vehicle events...
 --------
    Event.bind("onVehicleUpdate", onVehicleUpdate)
 -- Event.bind("onPlayerEnteringVehicle", onPlayerEnteringVehicle) -- Available as: onPlayerRequestEnterVehicle
 -- Event.bind("onPlayerEnterVehicle", onPlayerEnterVehicle) -- Available
 -- Event.bind("onPlayerExitVehicle", onPlayerExitVehicle) -- Available
    Event.bind("onVehicleExplode", onVehicleExplode)
    Event.bind("onVehicleRespawn", onVehicleRespawn)
 -- Event.bind("onVehicleHealthChange", onVehicleHealthChange)  -- Can be done manually using onVehicleUpdate
 -- Event.bind("onVehicleMove", onVehicleMove) -- Can be done manually using onVehicleUpdate
 --------
 -- Pickup events...
 --------
    Event.bind("onPickupPickAttempt", onPickupPickAttempt)
    Event.bind("onPickupPicked", onPickupPicked)
    Event.bind("onPickupRespawn", onPickupRespawn)
 --------
 -- Object events...
 --------
    Event.bind("onObjectShot", onObjectShot)
    Event.bind("onObjectTouch", onObjectTouch)
 --------
 -- Checkpoint events...
 --------
    Event.bind("onCheckpointEnter", onCheckpointEnter)
    Event.bind("onCheckpointExit", onCheckpointExit)
 --------
 -- Bind events...
 --------
    Event.bind("onPlayerKeyDown", onPlayerKeyDown)
    Event.bind("onPlayerKeyUp", onPlayerKeyUp)
 --------
 -- The end.
 --------

Clone this wiki locally