<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stefhany Santos</title>
    <description>The latest articles on DEV Community by Stefhany Santos (@stefhanysantos).</description>
    <link>https://dev.to/stefhanysantos</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1431840%2F4a27742f-ac6f-4b37-8ec1-960cbdea41ac.jpg</url>
      <title>DEV Community: Stefhany Santos</title>
      <link>https://dev.to/stefhanysantos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stefhanysantos"/>
    <language>en</language>
    <item>
      <title>Primeiros passos com FiveM: Nativos, Frameworks e meu primeiro ensure</title>
      <dc:creator>Stefhany Santos</dc:creator>
      <pubDate>Tue, 02 Jun 2026 15:34:17 +0000</pubDate>
      <link>https://dev.to/stefhanysantos/primeiros-passos-com-fivem-nativos-frameworks-e-meu-primeiro-ensure-3j7a</link>
      <guid>https://dev.to/stefhanysantos/primeiros-passos-com-fivem-nativos-frameworks-e-meu-primeiro-ensure-3j7a</guid>
      <description>&lt;p&gt;Recentemente comecei meus estudos em desenvolvimento para servidores &lt;strong&gt;FiveM&lt;/strong&gt;, com foco em bases como &lt;strong&gt;vRPex&lt;/strong&gt; e &lt;strong&gt;Creative&lt;/strong&gt;, que são bastante utilizadas no cenário brasileiro de servidores de roleplay.&lt;/p&gt;

&lt;p&gt;Como venho do desenvolvimento &lt;strong&gt;Front-End&lt;/strong&gt;, principalmente trabalhando com interfaces, componentização e integração com APIs, decidi documentar meus estudos para organizar melhor o aprendizado e também compartilhar minha evolução.&lt;/p&gt;

&lt;p&gt;Neste primeiro artigo, vou registrar os principais pontos da minha primeira aula: &lt;strong&gt;nativos, frameworks e a estrutura inicial de um resource no FiveM&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é FiveM?
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;FiveM&lt;/strong&gt; é uma plataforma que permite criar servidores modificados para GTA V, possibilitando experiências personalizadas como servidores de roleplay, sistemas de empregos, economia, facções, lojas, garagens, inventários, interfaces e muito mais.&lt;/p&gt;

&lt;p&gt;Dentro do FiveM, o desenvolvimento pode envolver várias linguagens e tecnologias, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lua;&lt;/li&gt;
&lt;li&gt;JavaScript;&lt;/li&gt;
&lt;li&gt;HTML;&lt;/li&gt;
&lt;li&gt;CSS;&lt;/li&gt;
&lt;li&gt;MySQL;&lt;/li&gt;
&lt;li&gt;frameworks específicos para RP;&lt;/li&gt;
&lt;li&gt;interfaces NUI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No meu caso, estou começando pela base mais comum em muitos servidores brasileiros: &lt;strong&gt;Lua + vRPex/Creative&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Nativos no FiveM
&lt;/h2&gt;

&lt;p&gt;Na aula, entendi que existem códigos chamados de &lt;strong&gt;nativos&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Os nativos são funções fornecidas pelo próprio ambiente do FiveM/GTA, permitindo interagir diretamente com elementos do jogo.&lt;/p&gt;

&lt;p&gt;Com eles, é possível fazer coisas como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;criar blips no mapa;&lt;/li&gt;
&lt;li&gt;desenhar markers;&lt;/li&gt;
&lt;li&gt;pegar coordenadas do player;&lt;/li&gt;
&lt;li&gt;manipular veículos;&lt;/li&gt;
&lt;li&gt;detectar ações do jogador;&lt;/li&gt;
&lt;li&gt;criar threads;&lt;/li&gt;
&lt;li&gt;interagir com entidades do mundo do GTA.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um exemplo simples de estrutura usando Lua seria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="n"&gt;CreateThread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Thread rodando"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa estrutura mostra uma thread sendo executada continuamente, com uma pausa de 1 segundo entre cada execução.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é Citizen?
&lt;/h2&gt;

&lt;p&gt;Durante a aula também apareceu o conceito de &lt;strong&gt;Citizen&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;De forma simples, entendi o Citizen como uma biblioteca/base principal usada pelo FiveM para fornecer vários códigos nativos.&lt;/p&gt;

&lt;p&gt;Ele ajuda o script a conversar com o ambiente do jogo, permitindo executar ações dentro do GTA V através do FiveM.&lt;/p&gt;

&lt;p&gt;Porém, o Citizen sozinho não entrega toda a estrutura necessária para criar uma cidade RP completa.&lt;/p&gt;

&lt;p&gt;Por exemplo, ele não resolve sozinho coisas como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sistema de identidade;&lt;/li&gt;
&lt;li&gt;inventário;&lt;/li&gt;
&lt;li&gt;permissões;&lt;/li&gt;
&lt;li&gt;whitelist;&lt;/li&gt;
&lt;li&gt;economia;&lt;/li&gt;
&lt;li&gt;conexão organizada com banco de dados;&lt;/li&gt;
&lt;li&gt;empregos;&lt;/li&gt;
&lt;li&gt;grupos;&lt;/li&gt;
&lt;li&gt;comandos administrativos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para isso, normalmente usamos um &lt;strong&gt;framework&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é um framework no FiveM?
&lt;/h2&gt;

&lt;p&gt;Um &lt;strong&gt;framework&lt;/strong&gt; é uma estrutura de código que organiza e facilita o desenvolvimento de uma cidade RP.&lt;/p&gt;

&lt;p&gt;Ele usa os nativos do FiveM e cria uma camada mais prática para lidar com sistemas comuns de roleplay.&lt;/p&gt;

&lt;p&gt;Alguns exemplos de frameworks conhecidos são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;vRP;&lt;/li&gt;
&lt;li&gt;vRPex;&lt;/li&gt;
&lt;li&gt;Creative;&lt;/li&gt;
&lt;li&gt;ESX;&lt;/li&gt;
&lt;li&gt;QBCore;&lt;/li&gt;
&lt;li&gt;Qbox.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No curso que estou fazendo, o foco será em &lt;strong&gt;vRP&lt;/strong&gt;, principalmente em bases como &lt;strong&gt;vRPex&lt;/strong&gt; e &lt;strong&gt;Creative&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O framework ajuda a padronizar coisas como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pegar o usuário do jogador;&lt;/li&gt;
&lt;li&gt;validar permissões;&lt;/li&gt;
&lt;li&gt;trabalhar com inventário;&lt;/li&gt;
&lt;li&gt;controlar dinheiro;&lt;/li&gt;
&lt;li&gt;acessar dados do player;&lt;/li&gt;
&lt;li&gt;criar comandos;&lt;/li&gt;
&lt;li&gt;integrar sistemas com banco de dados.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Nativo vs Framework
&lt;/h2&gt;

&lt;p&gt;Uma forma simples que encontrei para entender a diferença:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Conceito&lt;/th&gt;
&lt;th&gt;Explicação&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nativo&lt;/td&gt;
&lt;td&gt;Função mais próxima do FiveM/GTA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;Estrutura que organiza sistemas de RP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resource&lt;/td&gt;
&lt;td&gt;Um script/módulo dentro do servidor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ensure&lt;/td&gt;
&lt;td&gt;Comando usado para iniciar um resource&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Exemplo prático:&lt;/p&gt;

&lt;p&gt;O nativo pode ser usado para desenhar um marker no mapa.&lt;/p&gt;

&lt;p&gt;O framework pode ser usado para verificar se o jogador tem permissão para acessar aquele marker.&lt;/p&gt;

&lt;p&gt;O resource organiza esse sistema em arquivos.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;ensure&lt;/code&gt; inicia esse resource no servidor.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é um resource?
&lt;/h2&gt;

&lt;p&gt;No FiveM, os scripts são organizados em módulos chamados &lt;strong&gt;resources&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Cada resource pode representar um sistema da cidade, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;banco;&lt;/li&gt;
&lt;li&gt;garagem;&lt;/li&gt;
&lt;li&gt;inventário;&lt;/li&gt;
&lt;li&gt;loja de carros;&lt;/li&gt;
&lt;li&gt;loja VIP;&lt;/li&gt;
&lt;li&gt;HUD;&lt;/li&gt;
&lt;li&gt;celular;&lt;/li&gt;
&lt;li&gt;sistema de empregos;&lt;/li&gt;
&lt;li&gt;sistema de facções;&lt;/li&gt;
&lt;li&gt;painel administrativo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um resource normalmente possui uma estrutura parecida com esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;meu_resource/
│
├── fxmanifest.lua
├── client.lua
├── server.lua
├── config.lua
└── html/
    ├── index.html
    ├── style.css
    └── script.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  O que é o &lt;code&gt;fxmanifest.lua&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;O &lt;code&gt;fxmanifest.lua&lt;/code&gt; é o arquivo que registra o resource no FiveM.&lt;/p&gt;

&lt;p&gt;É nele que informamos quais arquivos fazem parte do script e o que deve ser carregado no client, no server ou na interface.&lt;/p&gt;

&lt;p&gt;Exemplo básico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="n"&gt;fx_version&lt;/span&gt; &lt;span class="s1"&gt;'cerulean'&lt;/span&gt;
&lt;span class="n"&gt;game&lt;/span&gt; &lt;span class="s1"&gt;'gta5'&lt;/span&gt;

&lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="s1"&gt;'Meu Nome'&lt;/span&gt;
&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="s1"&gt;'Meu primeiro resource FiveM'&lt;/span&gt;
&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s1"&gt;'1.0.0'&lt;/span&gt;

&lt;span class="n"&gt;client_script&lt;/span&gt; &lt;span class="s1"&gt;'client.lua'&lt;/span&gt;
&lt;span class="n"&gt;server_script&lt;/span&gt; &lt;span class="s1"&gt;'server.lua'&lt;/span&gt;
&lt;span class="n"&gt;shared_script&lt;/span&gt; &lt;span class="s1"&gt;'config.lua'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse arquivo é essencial para que o FiveM entenda como carregar o resource.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é &lt;code&gt;ensure&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Depois de criar um resource, precisamos iniciar ele no servidor.&lt;/p&gt;

&lt;p&gt;Para isso usamos o comando &lt;code&gt;ensure&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ensure meu_resource
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse comando normalmente fica no arquivo de configuração do servidor.&lt;/p&gt;

&lt;p&gt;Ele diz ao servidor:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Carregue esse resource quando a cidade iniciar.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Client e Server no FiveM
&lt;/h2&gt;

&lt;p&gt;Um dos pontos mais importantes da aula foi entender a diferença entre &lt;strong&gt;client&lt;/strong&gt; e &lt;strong&gt;server&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;client.lua&lt;/code&gt; roda no lado do jogador, ou seja, na máquina de quem está jogando.&lt;/p&gt;

&lt;p&gt;Ele normalmente lida com coisas visuais e interações locais, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;criar blips;&lt;/li&gt;
&lt;li&gt;desenhar markers;&lt;/li&gt;
&lt;li&gt;detectar teclas pressionadas;&lt;/li&gt;
&lt;li&gt;abrir interfaces;&lt;/li&gt;
&lt;li&gt;pegar coordenadas;&lt;/li&gt;
&lt;li&gt;executar animações;&lt;/li&gt;
&lt;li&gt;mostrar informações na tela.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Server
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;server.lua&lt;/code&gt; roda no lado do servidor.&lt;/p&gt;

&lt;p&gt;Ele deve cuidar das partes mais importantes e sensíveis, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validar dinheiro;&lt;/li&gt;
&lt;li&gt;validar permissões;&lt;/li&gt;
&lt;li&gt;conferir itens;&lt;/li&gt;
&lt;li&gt;salvar dados;&lt;/li&gt;
&lt;li&gt;buscar dados no banco;&lt;/li&gt;
&lt;li&gt;registrar logs;&lt;/li&gt;
&lt;li&gt;aplicar regras do sistema.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uma regra importante que já aprendi:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nunca confiar totalmente no client.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tudo que envolve dinheiro, item, permissão ou dado importante precisa ser validado no server.&lt;/p&gt;




&lt;h2&gt;
  
  
  Onde entra a NUI?
&lt;/h2&gt;

&lt;p&gt;Como venho do Front-End, essa parte chamou bastante minha atenção.&lt;/p&gt;

&lt;p&gt;No FiveM, a &lt;strong&gt;NUI&lt;/strong&gt; é a interface visual de um sistema.&lt;/p&gt;

&lt;p&gt;Ela pode ser feita com tecnologias como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML;&lt;/li&gt;
&lt;li&gt;CSS;&lt;/li&gt;
&lt;li&gt;JavaScript;&lt;/li&gt;
&lt;li&gt;React;&lt;/li&gt;
&lt;li&gt;Vue;&lt;/li&gt;
&lt;li&gt;jQuery.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A NUI seria como o “front-end” de um script.&lt;/p&gt;

&lt;p&gt;Ela pode ser usada em sistemas como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;banco;&lt;/li&gt;
&lt;li&gt;garagem;&lt;/li&gt;
&lt;li&gt;loja de carros;&lt;/li&gt;
&lt;li&gt;inventário;&lt;/li&gt;
&lt;li&gt;HUD;&lt;/li&gt;
&lt;li&gt;celular;&lt;/li&gt;
&lt;li&gt;painel administrativo;&lt;/li&gt;
&lt;li&gt;tablet policial;&lt;/li&gt;
&lt;li&gt;loja VIP.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um fluxo simples seria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NUI / Interface
      ↓
Client.lua
      ↓
Server.lua
      ↓
Banco de dados
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou seja, o jogador interage com a interface, a interface conversa com o client, o client chama o server e o server valida ou salva as informações.&lt;/p&gt;




&lt;h2&gt;
  
  
  Banco de dados
&lt;/h2&gt;

&lt;p&gt;O servidor também pode se comunicar com banco de dados, geralmente MySQL.&lt;/p&gt;

&lt;p&gt;O banco é usado para salvar informações como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;jogadores;&lt;/li&gt;
&lt;li&gt;veículos;&lt;/li&gt;
&lt;li&gt;dinheiro;&lt;/li&gt;
&lt;li&gt;casas;&lt;/li&gt;
&lt;li&gt;inventário;&lt;/li&gt;
&lt;li&gt;empregos;&lt;/li&gt;
&lt;li&gt;facções;&lt;/li&gt;
&lt;li&gt;multas;&lt;/li&gt;
&lt;li&gt;histórico de ações.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O fluxo correto é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client → Server → Banco de Dados
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O client não deve acessar o banco diretamente.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparando com desenvolvimento web
&lt;/h2&gt;

&lt;p&gt;Como venho do Front-End, fiz essa comparação para entender melhor:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Desenvolvimento Web&lt;/th&gt;
&lt;th&gt;FiveM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Front-End&lt;/td&gt;
&lt;td&gt;NUI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Back-End&lt;/td&gt;
&lt;td&gt;Server.lua&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service/API call&lt;/td&gt;
&lt;td&gt;Eventos client/server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Banco de dados&lt;/td&gt;
&lt;td&gt;MySQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configuração&lt;/td&gt;
&lt;td&gt;Config.lua&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Módulo/projeto&lt;/td&gt;
&lt;td&gt;Resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start do projeto&lt;/td&gt;
&lt;td&gt;Ensure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Framework back-end&lt;/td&gt;
&lt;td&gt;vRPex/Creative/QBCore/Qbox&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Essa comparação me ajudou bastante a entender que o FiveM também tem uma separação de responsabilidades.&lt;/p&gt;

&lt;p&gt;A diferença é que tudo acontece dentro do contexto do jogo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resumo da aula
&lt;/h2&gt;

&lt;p&gt;Nesta primeira aula, aprendi que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o FiveM usa nativos para interagir com o GTA;&lt;/li&gt;
&lt;li&gt;o Citizen fornece várias funções base para o ambiente FiveM;&lt;/li&gt;
&lt;li&gt;frameworks como vRPex e Creative organizam sistemas de roleplay;&lt;/li&gt;
&lt;li&gt;cada script é estruturado como um resource;&lt;/li&gt;
&lt;li&gt;o &lt;code&gt;fxmanifest.lua&lt;/code&gt; registra o resource;&lt;/li&gt;
&lt;li&gt;o &lt;code&gt;ensure&lt;/code&gt; inicia o resource no servidor;&lt;/li&gt;
&lt;li&gt;o &lt;code&gt;client.lua&lt;/code&gt; roda na máquina do jogador;&lt;/li&gt;
&lt;li&gt;o &lt;code&gt;server.lua&lt;/code&gt; roda no servidor;&lt;/li&gt;
&lt;li&gt;a NUI representa a interface visual;&lt;/li&gt;
&lt;li&gt;o banco de dados deve ser acessado pelo server;&lt;/li&gt;
&lt;li&gt;validações importantes devem ficar no servidor.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Próximo passo
&lt;/h2&gt;

&lt;p&gt;Meu próximo objetivo é criar meu primeiro resource simples com:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;fxmanifest.lua&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;client.lua&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;server.lua&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;config.lua&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quero praticar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;iniciar o resource com &lt;code&gt;ensure&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;criar um comando simples;&lt;/li&gt;
&lt;li&gt;enviar evento do client para o server;&lt;/li&gt;
&lt;li&gt;imprimir mensagens no console;&lt;/li&gt;
&lt;li&gt;entender melhor a comunicação client/server.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Essa primeira aula foi importante para entender a base do desenvolvimento FiveM.&lt;/p&gt;

&lt;p&gt;Mesmo sendo um ambiente diferente do desenvolvimento web tradicional, consegui perceber várias conexões com o que já conheço como Front-End.&lt;/p&gt;

&lt;p&gt;Principalmente na parte de NUI, onde posso aplicar conhecimentos de interface, experiência do usuário e integração com lógica de sistema.&lt;/p&gt;

&lt;p&gt;A ideia agora é continuar estudando Lua, vRPex, MySQL e NUI para começar a criar sistemas próprios para servidores de roleplay.&lt;/p&gt;

&lt;p&gt;Este artigo é o primeiro registro da minha jornada estudando desenvolvimento para FiveM.&lt;/p&gt;

</description>
      <category>lua</category>
      <category>gamedev</category>
      <category>estudos</category>
    </item>
    <item>
      <title>Como rodar seu Front-end no PC pessoal e o Backend (.NET) na máquina da empresa usando Ngrok</title>
      <dc:creator>Stefhany Santos</dc:creator>
      <pubDate>Fri, 27 Feb 2026 09:21:18 +0000</pubDate>
      <link>https://dev.to/stefhanysantos/como-expor-sua-api-local-em-net-https-com-ngrok-sem-erros-de-host-e-cors-3ef3</link>
      <guid>https://dev.to/stefhanysantos/como-expor-sua-api-local-em-net-https-com-ngrok-sem-erros-de-host-e-cors-3ef3</guid>
      <description>&lt;p&gt;Se você trabalha com desenvolvimento, talvez já tenha passado por esta situação:&lt;/p&gt;

&lt;p&gt;Você tem um PC pessoal super rápido, mas precisa usar a máquina corporativa (normalmente mais lenta) por causa da VPN para acessar o banco de dados da empresa.&lt;/p&gt;

&lt;p&gt;Trabalhar no Front-end com a máquina travando acaba com qualquer produtividade.&lt;/p&gt;

&lt;p&gt;A solução?&lt;/p&gt;

&lt;p&gt;Rodar o &lt;strong&gt;Backend na máquina da empresa&lt;/strong&gt; e o &lt;strong&gt;Front-end no seu PC pessoal&lt;/strong&gt;, usando o &lt;strong&gt;Ngrok&lt;/strong&gt; para criar um túnel seguro entre os dois.&lt;/p&gt;

&lt;p&gt;Mas, se o seu Backend for em &lt;strong&gt;.NET&lt;/strong&gt;, você vai perceber que rodar um simples comando do Ngrok não funciona de primeira.&lt;/p&gt;

&lt;p&gt;Neste artigo, vou te mostrar o &lt;em&gt;pulo do gato&lt;/em&gt; para resolver isso.&lt;/p&gt;




&lt;h1&gt;
  
  
  1️⃣ Autenticando o Ngrok
&lt;/h1&gt;

&lt;p&gt;Antes de tudo, baixe o Ngrok e adicione seu Authtoken.&lt;/p&gt;

&lt;p&gt;Você encontra esse comando no painel do Ngrok, logo na tela inicial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6chvex7upiuvktth2eq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6chvex7upiuvktth2eq.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois, basta rodar o comando no terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok config add-authtoken SEU_TOKEN_AQUI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso vincula sua máquina à sua conta.&lt;/p&gt;




&lt;h1&gt;
  
  
  2️⃣ O Problema com .NET e Ngrok
&lt;/h1&gt;

&lt;p&gt;Por padrão, aplicações .NET:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rodam em &lt;code&gt;https://localhost:5001&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Usam HTTPS com certificado de desenvolvimento&lt;/li&gt;
&lt;li&gt;Fazem validação rigorosa do Host Header&lt;/li&gt;
&lt;li&gt;Podem bloquear requisições externas por política de CORS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se você simplesmente rodar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http 5001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Ngrok vai tentar criar um túnel HTTP simples.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resultado? ❌&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Você pode receber:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Erro de CORS
&lt;/li&gt;
&lt;li&gt;400 Bad Request
&lt;/li&gt;
&lt;li&gt;Erro de Host inválido
&lt;/li&gt;
&lt;li&gt;Falha de redirecionamento HTTPS
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isso acontece porque:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O .NET espera HTTPS
&lt;/li&gt;
&lt;li&gt;O Host recebido não será &lt;code&gt;localhost&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A requisição chega com domínio externo (&lt;code&gt;.ngrok-free.dev&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  3️⃣ A Solução (O Comando Mágico)
&lt;/h1&gt;

&lt;p&gt;O segredo é dizer ao Ngrok duas coisas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Que o destino já é HTTPS
&lt;/li&gt;
&lt;li&gt;Que ele deve reescrever o Host Header
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http https://localhost:5001 &lt;span class="nt"&gt;--host-header&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"localhost:5001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔎 O que esse comando faz?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;https://localhost:5001&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Informa ao Ngrok que o backend já está rodando em HTTPS.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;--host-header="localhost:5001"&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Reescreve o cabeçalho da requisição.&lt;/p&gt;

&lt;p&gt;Quando a requisição chega na sua API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O .NET lê o Host como &lt;code&gt;localhost:5001&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A validação passa&lt;/li&gt;
&lt;li&gt;O roteamento funciona corretamente&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 Isso evita erros de Host inválido e problemas comuns de CORS relacionados ao domínio inesperado.&lt;/p&gt;




&lt;h1&gt;
  
  
  4️⃣ Configurando no Front-end
&lt;/h1&gt;

&lt;p&gt;Após rodar o comando, o Ngrok gera uma URL pública:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://seu-link.ngrok-free.dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, no seu projeto Front-end, atualize a variável de ambiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API_URL=https://seu-link.ngrok-free.dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reinicie o projeto e pronto 🚀&lt;/p&gt;

&lt;p&gt;Agora você pode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Desenvolver a interface no seu PC rápido
&lt;/li&gt;
&lt;li&gt;Consumir a API na máquina corporativa
&lt;/li&gt;
&lt;li&gt;Acessar o banco via VPN
&lt;/li&gt;
&lt;li&gt;Trabalhar com performance real
&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🎁 Bônus: O Ngrok é muito mais que um túnel
&lt;/h1&gt;

&lt;p&gt;Além de resolver o problema de conectividade, o Ngrok oferece recursos poderosos.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔐 Segurança de Endpoints
&lt;/h2&gt;

&lt;p&gt;Você pode proteger seu túnel com:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OAuth
&lt;/li&gt;
&lt;li&gt;Restrição de IP
&lt;/li&gt;
&lt;li&gt;Validação JWT
&lt;/li&gt;
&lt;li&gt;Basic Authentication
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tudo configurado direto no painel.&lt;/p&gt;

&lt;h2&gt;
  
  
  📊 Monitoramento de Tráfego
&lt;/h2&gt;

&lt;p&gt;O Ngrok possui um inspetor de tráfego em tempo real.&lt;/p&gt;

&lt;p&gt;Você pode visualizar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Headers
&lt;/li&gt;
&lt;li&gt;Payload
&lt;/li&gt;
&lt;li&gt;Status code
&lt;/li&gt;
&lt;li&gt;Tempo de resposta
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ideal para debugar integrações.&lt;/p&gt;




&lt;h1&gt;
  
  
  📚 Conclusão
&lt;/h1&gt;

&lt;p&gt;Com o comando correto, é possível expor uma API .NET rodando em HTTPS sem erros de Host ou CORS, mantendo segurança e produtividade.&lt;/p&gt;

&lt;p&gt;Essa abordagem permite trabalhar com performance real no Front-end sem abrir mão do acesso ao banco via VPN.&lt;/p&gt;




&lt;p&gt;✍️ &lt;strong&gt;Stefhany Santos&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Software Engineer&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>dotnet</category>
      <category>ngrok</category>
      <category>produtividade</category>
    </item>
    <item>
      <title>Como consertei a câmera de um port de PC usando a API do Windows (Unity IL2CPP Modding)</title>
      <dc:creator>Stefhany Santos</dc:creator>
      <pubDate>Sun, 22 Feb 2026 20:10:17 +0000</pubDate>
      <link>https://dev.to/stefhanysantos/como-consertei-a-camera-de-um-port-de-pc-usando-a-api-do-windows-unity-il2cpp-modding-38jo</link>
      <guid>https://dev.to/stefhanysantos/como-consertei-a-camera-de-um-port-de-pc-usando-a-api-do-windows-unity-il2cpp-modding-38jo</guid>
      <description>&lt;p&gt;Fala, comunidade! 👋&lt;/p&gt;

&lt;p&gt;Recentemente, me deparei com um problema clássico no mundo dos games: um jogo mobile (&lt;em&gt;Heartopia&lt;/em&gt;) ganhou um port para PC, mas trouxe consigo todos os controles de toque. O resultado? Para girar a câmera, o jogador precisava &lt;strong&gt;segurar o clique esquerdo e arrastar o mouse&lt;/strong&gt;. Uma experiência de UX terrível para quem joga no teclado e mouse.&lt;/p&gt;

&lt;p&gt;Como desenvolvedora, eu não ia simplesmente aceitar isso. Decidi criar um mod para transformar essa câmera em um "Free Look 360º" contínuo, nativo de jogos de PC. O que parecia simples virou um desafio de engenharia reversa e manipulação de SO.&lt;/p&gt;

&lt;p&gt;Bem-vindos ao &lt;strong&gt;Heartopia PC Camera Fix&lt;/strong&gt;, o primeiro projeto open-source do meu estúdio indie, &lt;strong&gt;Lovel Studio&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚧 O Desafio: Unity IL2CPP e o Input Manager
&lt;/h3&gt;

&lt;p&gt;O jogo foi compilado em &lt;strong&gt;IL2CPP&lt;/strong&gt;, o que já dificulta bastante a engenharia reversa se comparado ao Mono tradicional. A arquitetura original utilizava o &lt;em&gt;New Unity Input System&lt;/em&gt; altamente acoplado para mobile (&lt;code&gt;ScriptsRefactory.BaseService.Input.InputManager&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Tentar interceptar o &lt;code&gt;UnityEngine.Input&lt;/code&gt; diretamente via Harmony Hooks estava quebrando o jogo. A solução? Fazer um &lt;em&gt;bypass&lt;/em&gt; na engine e lidar diretamente com o Windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠️ A Solução: C# + &lt;code&gt;user32.dll&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Criei um plugin em &lt;strong&gt;BepInEx 6&lt;/strong&gt; e adotei uma abordagem de "Esteira Virtual" usando a API nativa do Windows.&lt;/p&gt;

&lt;p&gt;A arquitetura final do mod (v2.5.0) faz o seguinte:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. O Paradoxo da Esteira (Virtual Treadmill)&lt;/strong&gt;&lt;br&gt;
Quando o jogador aperta &lt;code&gt;ALT&lt;/code&gt;, eu confino o cursor e simulo um &lt;code&gt;MOUSEEVENTF_RIGHTDOWN&lt;/code&gt;. Para permitir o giro infinito (360º), eu leio as coordenadas do monitor via &lt;code&gt;ClientToScreen&lt;/code&gt; e teletransporto o cursor (&lt;code&gt;SetCursorPos&lt;/code&gt;) de volta para o centro sempre que ele atinge uma margem de 100 pixels. É um &lt;em&gt;loop&lt;/em&gt; infinito e invisível de arrasto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Segurança de Interface (WndProc Hook)&lt;/strong&gt;&lt;br&gt;
O maior bug inicial era: enquanto o jogador girava a câmera livremente, o jogo continuava registrando "cliques" invisíveis na interface, fazendo a personagem atacar do nada. &lt;br&gt;
Para resolver isso, criei um &lt;strong&gt;Hook direto no WndProc da janela do jogo&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="nf"&gt;WndProcHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="n"&gt;hWnd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="n"&gt;wParam&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="n"&gt;lParam&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Bloqueia cliques esquerdos apenas quando a câmera Lovel está ativa&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isLocked&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;WM_LBUTTONDOWN&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;WM_LBUTTONUP&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;WM_LBUTTONDBLCLK&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oldWndProc&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zero&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;CallWindowProc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oldWndProc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hWnd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wParam&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lParam&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso literalmente cega o jogo para cliques físicos esquerdos enquanto o modo de câmera está ativo. Um bloqueio limpo no nível do sistema operacional.&lt;/p&gt;

&lt;h3&gt;
  
  
  🐛 Aonde preciso da ajuda de vocês (Open Source)
&lt;/h3&gt;

&lt;p&gt;Apesar da estabilidade excelente, há um &lt;em&gt;Known Issue&lt;/em&gt;: a câmera sofre um leve &lt;em&gt;stuttering&lt;/em&gt; ocasional.&lt;br&gt;
Isso acontece porque a Main Thread da Unity às vezes dá gargalos pesados (ex: carregando chunks ou texturas) e o jogo "perde" o frame exato em que a esteira virtual reseta o mouse para o centro, quebrando o movimento por uma fração de segundo.&lt;/p&gt;

&lt;p&gt;O projeto está sob &lt;strong&gt;Licença MIT&lt;/strong&gt; no GitHub. Se você manda bem em C#, engenharia reversa ou otimização de Unity, adoraria receber seus Pull Requests! O objetivo é encontrar os &lt;em&gt;offsets&lt;/em&gt; corretos para um Hook nativo na classe controladora de câmera via Harmony, eliminando a dependência da &lt;code&gt;user32.dll&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;&lt;a href="https://github.com/L0V3L/Heartopia-PC-Camera-Fix" rel="noopener noreferrer"&gt;Acesse o repositório do Heartopia Camera Fix aqui&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se você joga o game, a aba de &lt;em&gt;Releases&lt;/em&gt; já tem o &lt;code&gt;.zip&lt;/code&gt; pronto no modelo &lt;em&gt;Drag &amp;amp; Drop&lt;/em&gt; pra facilitar a vida.&lt;/p&gt;

&lt;p&gt;Adoraria saber a opinião de vocês sobre outras abordagens para injetar &lt;em&gt;inputs&lt;/em&gt; em jogos IL2CPP. Como vocês resolveriam esse &lt;em&gt;stuttering&lt;/em&gt; da Main Thread?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Desenvolvido com muita quebra de cabeça por Stefhany (Lovel Studio)&lt;/em&gt; 💜&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Automatizando posts do dev.to no README do GitHub com GitHub Actions</title>
      <dc:creator>Stefhany Santos</dc:creator>
      <pubDate>Tue, 17 Feb 2026 13:22:38 +0000</pubDate>
      <link>https://dev.to/stefhanysantos/teste-7ml</link>
      <guid>https://dev.to/stefhanysantos/teste-7ml</guid>
      <description>&lt;p&gt;Manter o README do GitHub atualizado com seus conteúdos é uma forma simples (e poderosa) de mostrar consistência, aprendizado contínuo e presença na comunidade dev.&lt;/p&gt;

&lt;p&gt;Neste post, vou mostrar como automatizei a exibição dos meus artigos do Dev.to diretamente no README, usando GitHub Actions sem scripts complexos e sem manutenção manual.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Por que fazer isso?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Seu README fica sempre atualizado&lt;/li&gt;
&lt;li&gt;✅ Mostra que você produz conteúdo técnico&lt;/li&gt;
&lt;li&gt;✅ Recrutadores veem seus artigos logo de cara&lt;/li&gt;
&lt;li&gt;✅ Zero trabalho manual depois da configuração&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 A solução
&lt;/h2&gt;

&lt;p&gt;Usei uma GitHub Action pronta chamada blog-post-workflow, que consome feeds RSS (como o do Dev.to) e injeta os posts automaticamente no README.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ Passo 1 — Criar o workflow&lt;/strong&gt;&lt;br&gt;
No seu repositório, crie o arquivo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.github/workflows/blog-posts.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conteúdo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Latest blog post workflow

on:
  schedule:
    - cron: '0 0 * * *'
  workflow_dispatch:

jobs:
  update-readme-with-blog:
    name: Update this repo's README with latest blog posts
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Pull in dev.to posts
        uses: gautamkrishnar/blog-post-workflow@v1
        with:
          feed_list: "https://dev.to/feed/stefhanysantos/"
          max_post_count: 3
          date_format: "dd mmm yyyy"
          template: |
            &amp;lt;div&amp;gt;
              &amp;lt;h4&amp;gt;&amp;lt;a href="$url"&amp;gt;$title&amp;lt;/a&amp;gt; | &amp;lt;em&amp;gt;📅 $date&amp;lt;/em&amp;gt;&amp;lt;/h4&amp;gt;
            &amp;lt;/div&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Roda diariamente&lt;/li&gt;
&lt;li&gt;Pode ser executado manualmente&lt;/li&gt;
&lt;li&gt;Atualiza o README automaticamente com os últimos posts&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;🧷 Passo 2 — Preparar o README&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;No local onde você quer que os posts apareçam, adicione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- BLOG-POST-LIST:START --&amp;gt;
&amp;lt;!-- BLOG-POST-LIST:END --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É exatamente entre esses comentários que a action vai renderizar os artigos.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✨ Resultado final
&lt;/h3&gt;

&lt;p&gt;No README, os posts aparecem assim:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Título do artigo&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;📅 10 fev 2026&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🚀 Outro artigo técnico&lt;br&gt;
📅 05 fev 2026&lt;/p&gt;

&lt;p&gt;Simples, limpo e profissional.&lt;/p&gt;




&lt;h3&gt;
  
  
  💡 Dica extra
&lt;/h3&gt;

&lt;p&gt;Você pode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filtrar por tags&lt;/li&gt;
&lt;li&gt;Customizar o template com HTML&lt;/li&gt;
&lt;li&gt;Limitar quantidade de posts&lt;/li&gt;
&lt;li&gt;Usar isso como portfólio técnico vivo&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🚧 Conclusão
&lt;/h3&gt;

&lt;p&gt;Automatizar pequenas coisas como essa faz diferença no longo prazo.&lt;br&gt;
Seu GitHub deixa de ser apenas código e passa a contar a sua história como dev.&lt;/p&gt;

&lt;h1&gt;
  
  
  braziliandevs #ptbr
&lt;/h1&gt;

</description>
      <category>braziliandevs</category>
      <category>github</category>
      <category>career</category>
    </item>
  </channel>
</rss>
