delarco

Engineering, coding and games

A Evolução dos Battle Droids: Numa galáxia não tão distante…

(First of all: tenha em mente que comecei a escrever esse texto em fevereiro de 2011)

Esses tempos comprei o hipado jogo Star Wars: Force Unleashed, numa promoção fodástica do Steam. Sempre fui fã incondicional de Star Wars e, como todo bom gamer, sei que jogos baseados em filmes (ou séries… ou qlq coisa que passe na TV) sempre são uma grande mierda. Botei fé nesse, pois (além de ser super-ultra-mega-blaster-hipado) o primeiro jogo relacionado à Star Wars na qual tive contato foi o Star Wars Jedi Knight II: Jedi Outcast, que achei MUITO bom. A jogabilidade não era complexa, eu tinha um sabre de luz, podia usar a Força, etc… claro que o fator principal foi: RODAVA NO MEU PC.

Este parágrafo é apenas um desabafo. Voltando ao Jedi Outcast, eu pirava usando o Force Grip nos Stormtroopers, refletindo disparo de armas laser com meu sabre e tal, mas… PUTA QUE PARIU! O jogo não precisava ser tão dificil. Caraleo!!! Okay, não lembro se o jogo era tão dificil assim, pois faz uns 6 anos que joguei. Só lembro que sofri pra matar o último chefe. E só consegui pq ele derrubou um pilar de 453 toneladas em cima dele mesmo. Com o Force Unleashed foi a mesma coisa. Repito: PUTA QUE PARIU! Eu joguei no modo newbie-plus (normal), pois o que eu realmente gostos nos jogos é a história (eu sei, ESTÓRIA) e não mostrar que eu consigo passar a última fase do mundo especial, que só é habilitado depois de 712 horas de jogo e sacrifício de 90% da vida social, com o personagem mais fraco sem perder nada de vida. Spoilando muito agora, vc deve escolher se quer uma luta com o imperador Palpatine ou se quer terminar de surrar o fodástico Darth Vader. CARA! Quem em sã consciência pensaria em matar o Darth Vader? Eu, claro! Agora pensa num inimigo apelão, que me lembra os velhos tempos, onde zerar joguinhos de Super Nintendo e Mega Drive demandava um treino sério, disciplinado e bom estado de espírito, além de ser objetivo de vida para algumas pessoas. Pois 40 minutos depois, recomecei a fase e escolhi a outra batalha. Essa foi easy, mas fiquei chateado, pois achei que o sith comeria a loirinha que pilota a nave no final.

Enfim, após uma seção narguilástica de canela e menta, acompanhada de vinho branco de Dinalle, fiquei pensando nos trilhões de Stormtroopers que matei sem dó nem piedade. Eles têm família! Oh, Deus! Quantas mães e filhos desamparados, cuja vida eu desgracei, não estão passando fome? Pq eles simplesmente não  usam os desalmados Battle Droids, cuja única finalidade é preencher aquele vazio enorme entre os a introdução do game e o último Boss?

Foi aí que nesse momento de pura falta do que fazer, fiquei imaginando como surgiram os Battle Droids. Será que o objetivo inicial era criar guerreiros letais? Ou algum nerd forever alone não aguentava mais a vida solitária e desenvolveu um parceiro para “todos os momentos“? Como seria a evolução desse tipo de arma no mundo atual?

Bom… levando em conta as putisses que me fizeram passar na faculdade, o modo como os “empresários” da minha ex-cidade (São José do Hell Preto) pensam e a utilidade questionável da classe estagiário, cheguei à seguinte aproximação.

Prólogo

Como todo bom coordenador de ensino superior, o Sr. Darto Veider diz que os alunos devem se juntar para fazer um trabalho multidisciplinar que terá peso 87 na média final, enquanto as 900 provas que os alunos fizeram nos últimos meses terão peso 1 cada.

Algum aluno da Engenharia sem muito o que fazer cria um desenho simples. Um droid esquelético que pode imitar a maioria dos movimentos humanos.

Outro aluno de Ciências da Computação, por sua vez  já fez todo o design, diagramas de classe e nao-sei-mais-o-quê-UML (todo documentado pq o professor pediu) de um sistema de Inteligência Artificial que integra outros sistemas, como reconhecimento facial, e que é capaz de receber, processar e executar ordens simples. Até então, a única ordem que realmente funcionava era a de encontrar e baixar filme educativos de determinada atriz.

Os dois alunos se encontram no buteco, ambos bebados por causa do multidisciplinar. Deixarei de lado a parte em que eles conversam sobre a mãe do Sr. Veider e pularei para a parte em que eles juntam seus projetos e projetam o primeiro Battle Droid. O objetivo principal do Battle Droid era surtar durante a apresentação e assassinar lenta e dolorosamente o Sr. Veider, mas algo sai errado e o Droid apenas faz movimentos simples  que mostram todas suas possibilidades de uso, inclusive fazendo tchauzinho no final.

A apresentação é um sucesso e o Sr. Veider procura um telefone no Lado Negro da sua agenda de contatos. Três minutos e meio depois, antes mesmo de desmontarem o droid para devolver as peças da torradeira de suas maes, o Sr. Veider aparece com o Sr. Paltine. Este, acionista majoritário da Império S.A. oferece uma fortuna para os alunos, em troca das especificações técnicas, diagrama de classes, etc. Apesar da proposta inicial ser de 487 milhões, o valor final foi fixado em 150 reais, pois o código não estava todo comentado, faltava parte da documentação, casos de uso incompletos e parte do código foi copiado de um hello world (para VB5, já que os professores obrigaram a usar esta linguagem). Com as mãos num projeto tão promissor, o Sr. Palpa começa as pesquisas.

Continua…

COBOL: Parte 1 – Configurando o TinyCobol

A imagem acima foi a melhor que encontrei para ilustrar o preconceito que eu tinha em relação a linguagem COBOL. Ao meu ver, só usa COBOL aquele tipo de programador pré-histórico, que gosta de escovar bits e acha necessário contar quantos bytes foram “gastos” para carregar X dados e efetuar Y operações, controlando bit a bit os recursos do sistema, como se os computadores atuais (4+GB de RAM) não fossem capazes de suportar um arquivo texto de 40kb na memória e processar os algorítmos mais simples.

Mas então, por que aprender COBOL?

Como eu disse, havia um preconceito. Todo mundo é preconceituoso quando não conhece aquilo que critica. Saber economizar memória e ciclos da CPU pode não ser importante naquela calculadora que você desenvolveu na aula de introdução à JAVA, nem naquele “Hello World!”, que ocupa 10MB de RAM, feito em VB.NET… mas se um dia você se deparar com um algorítmo mais complexo, que exija o processamento de uma GRANDE quantidade de dados, vai perceber que a correta utilização dos recursos permite economizar tempo e evitar dores de cabeça.

Não que eu tenha mudado completamente meu conceito (prefiro C++, ainda mais com a homologação do padrão C++0X), mas percebi que não tem como fugir. Há uma certa escassez de programadores COBOL (com experiência), pois além de idosa e difícil se comparada com as linguagens de 4ª geração (e posteriores), não é uma linguagem voltada para aplicativos modernos.

De acordo com o Wikipedia,

COBOL é uma linguagem de programação de Terceira Geração. Este nome é a sigla de COmmon Business Oriented Language (Linguagem Orientada aos Negócios), que define seu objetivo principal em sistemas comerciais, financeiros e administrativos para empresas e governos.

wikipedia

Ou seja, como eu trabalho no maior banco público da América Latina e desde sempre visando a área de TI, resolvi que aprender algo novo pode ser bom para o currículo, além de não doer nem um pouco e prevenir o Alzheimer. Não que eu vá usar, mas vai saber…

Enfim, não pesquisei os melhores compiladores, nem as mais completas IDE’s. Meu objetivo é aprender COBOL da maneira mais simples e correta possível (ANSI), não me apegando às perfumarias oferecidas em ambientes profissionais. Então, acabei encontrando o TinyCOBOL.

O TinyCOBOL é um compilador grátis desenvolvido por um brasileiro e não oferece nenhuma ferramenta para vomitar lógica codificação. Então, você pode fazer como eu e usar o Notepad++ para escrever os fontes.

Levando em conta que não vou precisar de nenhuma biblioteca para estender as funcionalidades da linguagem por enquanto, baixei esse instalador do TinyCOBOL (do site  da InfoCont) que já deixa tudo no jeito para começar a programar, sem se preocupar com as configurações pós-instalação. Se o link anterior não funcionar, você pode baixar aqui também.

A instalação, assim como qualquer uma em ambiente Windows, é bem simples:

  1. Faça download do instalador (aqui também);
  2. 4x Avançar;
  3. Deixei pelo menos a primeira opção selecionada (Modifique as variáveis de ambiente);
  4. Avançar. Instalar;
  5. Se você instalou no diretório padrão (c:\tinycobol), então crie um atalho na sua área de trabalho para o tcobol.bat, que está c:\tinycobol\doc. Dentro desse mesmo diretório, o desenvolvedor incluiu dois documentos sobre interfaces possíveis de serem utilizadas com o tinycobol;
  6. Para compilar, execute o tcobol.bat e digite: htcobol arquivo.cob;

Eu prefiro compilar com o parâmetro -F, pois foça a verificação do formato do código. Em COBOl, os 7 primeiros caracteres de cada linha têm funções específicas. Então, na maioria das vezes, devem ser deixados em branco.

Para testar, crie um arquivo chamado HelloWorld.cob no seu C:\ e cole o código abaixo (retirado do wikipedia):

IDENTIFICATION DIVISION.
PROGRAM-ID. HELLOWORLD.
*
ENVIRONMENT DIVISION.
*
DATA DIVISION.
*
PROCEDURE DIVISION.
PARA-1.
DISPLAY "Hello, World!!".
*
STOP RUN.

Não esqueca de deixar uma linha em branco no final do arquivo (isso me rendeu alguns palavrões). Se não funcionar, os espaços na frente de cada linha devem estar incorretos (vou explicar mais sobre o formato dos arquivos .COB no próximo post). Então você pode baixar o arquivo aqui.

Para compilar: htcobol -F c:\HelloWorld.cob

Se funcionou, um arquivo HelloWorld.exe foi criado no mesmo diretório do HelloWorld.cob (c:\?).

É claro que eu vou demorar pra escrever algo sobre COBOL, pois TCC e vida não podem existir na mesma frase, então você pode começar lendo o zingCOBOL que, até então, foi minha principal fonte de referência sobre COBOL.

try2hack.nl: Level 4

O nível 4 é parecido com o 2, pois o processo de autenticação é feito por um objeto (nada de javascript com a senha). Dessa vez, temos um Applet.

Para começar, baixei o objeto. Depois usei esse descompilador java (é só arrastar o arquivo .class para cima do texto “Drop class and inner class files here“).

Eu não entendia muito de java quando cheguei no nível 4 pela primeira vez, mas olhando BEMMM o código, me parece que um outro arquivo (que contém a senha) é aberto para fazer a autenticação. Então o código abaixo me chamou a atenção:

this.infile = new String("level4");
try
{
   this.inURL = new URL(getCodeBase(), this.infile);
}
catch (MalformedURLException localMalformedURLException)
{
   getAppletContext().showStatus("Bad Counter URL:" + this.inURL);
}
inFile();

Primeiramente, o nome do arquivo é definido (“level4″). A princípio, parece estranho por não haver extensão, mas se acessarmos pelo endereço correto (“www.try2hack.nl/levels/level4“) podemos baixar o arquivo.

E, finalmente, ao abrir com o bloco de notas temos:

level5-fdvbdf.xhtml (link para o nível 5)
appletking (usuário)
pieceofcake (senha)

Apesar de simples, o nível 4 exigiu mais passos que os anteriores, porém o problema ainda é o mesmo: validação client-side.

O que aprender com o nível 4?

Apesar de os dados não estarem dispostos em texto puro, muito provavelmente existirá um descompilador para qualquer tipo de midia/objeto/bytecode que você utilizar. Você pode usar flash, applets, activex controls, etc… desde que a validação seja SEMPRE no servidor.

Software protegido pela Lei Divina?

Lembro que, em 2006, quando fazia estágio na SATEC (Seção de Tecnologia da Receita Federal), o grande amigo Marcos Gottardi encontrou um comentário do tipo “Código instável, não mexer” em um sistema interno. Levando em conta que foi desenvolvido por estagiários, não me assusta. Mas esse aqui realmente me faz ter medo:

try2hack.nl: Level 3

O nível 3 é um saco pra quem não sabe o que fazer. Primeiro: se você erra a senha ou cancela o prompt, você é redirecionado para o site da Disney.

Pô! Assim não dá pra ver o fonte… o botão direito não mostra o menu. Esse web-designer sacaneou legal! Que eu faço?

Começa descobrindo a tecla de atalho para ver o código (CTRL+U no meu Firefox) ou você pode encontrar esta opção no menu “Exibir”.

<script type="text/javascript">
 <!--
    pwd = prompt("Please enter the password for level 3:","");
if (pwd==PASSWORD){
alert("Allright!\nEntering Level 4 ...");
location.href = CORRECTSITE;
}
else {
alert("WRONG!\nBack to disneyland !!!");
location.href = WRONGSITE;
}
PASSWORD="AbCdE";
CORRECTSITE="level4-sfvfxc.xhtml";
WRONGSITE="http://www.disney.com";
 //-->
 </script>

Aí você, muito malandro, acha que a senha tá fácil e coloca lá: AbCdE
ou tenta acessar level4-sfvfxc.xhtml

Ai, caramba! Pero estoy seguro que el amor se acaba!

Se você olhar o código mais atentamente, pode ver que as variáveis recebem os valores APÓS a validação, ou seja, há algo errado.

É claro que você percebeu antes de eu falar, mas o código abaixo está meio estranho:

<script type="text/javascript" src="JavaScript"></script>

Como assim? o atributo “src” define o nome do arquivo que contém um script. Ou seja, se você acessar http://www.try2hack.nl/levels/JavaScript (Salvar link como…) poderá ver o valor inicial das variáveis:

PASSWORD = "try2hackrawks";
CORRECTSITE = "level4-kdnvxs.xhtml";
WRONGSITE = "http://www.disney.com";

Aí ficou fácil!

O que aprender com o nível 3?

A mesma coisa que nos outros dois níveis: não adianta tentar esconder. Se a senha estiver no computador do usuário, uma hora seu sistema será acessado por indivíduos não autorizados.

try2hack.nl: Level 2

O segundo nível ainda é um desgosto para qualquer um que se preocupa com segurança. Apesar do código de validação não estar exposto no código-fonte da página, os dados “Usuário” e “Senha” estão armazenados no arquivo “.swf” (flash), que exibe o formulário de login.

Ok! E como eu “abro” o swf?

Primeiro, vamos baixar o arquivo. Se você não sabe como baixar, é só clicar AQUI com o botão direito do mouse e selecionar a opção “Salvar link como…” (Firefox).

Para abrir o arquivo, você pode baixar um SWF Decompiler e ver o que o código faz exatamente. Mas como a segurança foi tão porcamente pensada, você pode usar o bloco de notas mesmo.

Abrindo o “level2.swf” no bloco de notas, basta localizar (F3) “txtUsername” ou “txtPassword”. O suposto programador é tão “bom” que, além de poder ver usuário e senha em texto puro, podemos ir para o próximo nível sem precisar efetuar a validação no site, pois sabemos que está em “./level3-.xhtml”. Não sabe onde colar isso? Darwin…

O que aprender com o nível 2?

Não adianta tentar esconder usuário e senha. Se você deixar esse tipo de validação para o computador do usuário, SEMPRE vai ter algum fidimascate que vai descobrir.

try2hack.nl: Level 1

try2hack.nl é um site que disponibiliza alguns desafios relacionados à segurança. Apesar de ser apenas um game, cada nível mostra um tipo de falha que ainda são comuns, graças à impudência de alguns administradores e programadores. Como eu tive uma certa dificuldade na maioria dos níveis, resolvi escrever sobre os métodos que utilizei, pois tenho certeza que alguém sabe uma maneira mais fácil.

Nível 1:
O primeiro nível é bem simples pode ser resolvido com uma rápida análise do código-fonte da página.

Quê?! Código-fonte?

Se você não sabe olhar o código-fonte de uma página, provavelmente não sabe o que é html e, muito menos, javascript. Ou seja, estude muito antes de tentar se aventurar nesse tipo de game.

Ok, qualquer ameba sabe que a validação de usuário/senha DEVE ser feita no servidor. Você pode até validar alguns outros campos (CPF, por exemplo) no browser com javascript, mas SEMPRE deve haver a mesma validação no servidor (burlar esse tipo de validação é relativamente simples).

Certo, olhando o código-fonte, achamos a senha no trecho:

<script type="text/javascript">
<!--
   function Try(passwd) {
      if(passwd == "h4x0r") {
         alert("Alright! On to level 2...");
         location.href = "level2-xfdgnh.xhtml";
      }
      else {
         alert("The password is incorrect. Please don't try again.");
         location.href = "http://www.disney.com/";
      }
 }
//-->
</script>

Será que existe MESMO alguém que ainda faz isso? Darwin… Darwin…

O que aprender com o nível 1?

Que, apesar de 90% dos usuários não saberem ler javascript ou se quer ver o código-fonte de uma página, não devemos deixar esse tipo de código/validação exposto para os usuários.

Criando Cheats: Prelúdio

Estudo programação à anos e sempre tive maior interesse no que se refere à arte expressa em pixels. Que sou grande fã de jogos eletrônicos (um mid-core gamer, não casual, nem hardcore) não há dúvidas… e essa paixão estende-se além do ato de jogar e apreciar momentos únicos, que apenas orientais extraterresters (leia Miyamoto) conseguem proporcionar.

Senta que lá vem história

Como todo bom gamer, não me contento em socar o último chefe e sair falando na escola (hoje em dia é twiter, né?) “ZEREI/TERMINEI/FECHEI MAIS UM JOGO”. Pq? A mágica está nos detalhes! Os detalhes que muitas vezes não percebemos quando jogamos pela primeira vez. Aquele canto que não serviu pra NADA durante o jogo, mas que estava lá para ser explorado.

Qual apaixonado por games que terminou Super Mario World e não fez questão de conseguir os 100%? Ou quis passar todas as fases do “ESPECIAL” que não tinham relação alguma com o final do jogo?

Quem já jogou The Legend Of Zelda: Ocarina Of Time e não quis pegar as 100 gold skultullas mesmo sabendo que os rupees ilimitados (que vc tem direito ao final da quest) não valem o esforço?

Mesmo sentindo ausência da mágica nos jogos atuais, ainda não consigo “aposentar” um jogo logo após terminá-lo.

Atualmente faço questão de TER o video-game para poder jogá-lo (adquiri um Super Nintendo recentemente e já estou cotando um Megadrive), mas é impossível comprar todos os cartuchos, até pq alguns nem são comercializados hj em dia (Atari, Nintendinho etc). Então, como todo gamer que possui um computador e sabe da existência dos emuladores (ZSNES!), baixei muitos jogos e terminei cada um deles.

Antes de continuar, queria deixar claro que não sou a favor da pirataria, apesar não ser completamente contra (tudo é relativo…).

Quem conhece um, sabe que a maior virtude do programador é a curiosidade. É claro que não fiquei apenas no “Load Rom/Save State/Load State” do ZSNES. Com o tempo fui descobrindo cada funcionalidade e o que me chamou a atenção foram os códigos que podiam ser inseridos para modificar a jogabilidade ou algum estado do jogo. Testei centenas de códigos em dezenas de jogos e chegou uma hora que não tinha como não me perguntar: como um código esquisito daquele (na época eu não sabia o que era base hexadecimal) podia fazer tanto “estrago” no jogo? E eu sabia que não podia ser nada projetado/previsto pelos programadores do jogo, pois não eram códigos digitados no controle (como uma sequencia de botões), ou inseridos no menu “cheat”.

Nesa fase, fiquei apenas na curiosidade mesmo, pois o material online sobre o asusnto era escasso e meu acesso à internet, mto raro. Tempos depois, qdo comprei o jogo Diablo (o 1 mesmo) e descobri que era possível jogar com outras pessoas na internet, passei várias madrugadas (contava os minutos antes das 00:00h para poder conectar) jogando com os, como diria o bomba, “amiguinhos virtuais“. Até que um gringo filho de uma borboleta entrou na minha “sala“, zerou todos meus stats e removeu todos os meus itens. Não que eu não tenha chutado o cachorro por isso, mas ao passar o susto (raiva, ódio e outros sentimentos sem nome), fui procurar saber sobre códigos/trapaças para Diablo (o termo cheater era novidade pra mim). Qual não foi minha surpresa ao descobrir que o tal programinha BoBaFeTT’s Diablo Trainer podia editar, não só os stats e itens, como podia acrescentar itens que nem mesmo existiam no jogo. Aquela curiosidade sobre como funcionavam os códigos no emulador ZSENS voltou repentinamente, somada ao incrivel fato de poder adicionar elementos que o jogo não possuia originalmente. Devo ter ficado uns 2 dias sem dormir para poder testar todas as opções e armas.

[OFF] Btw, até hj não sei se desligaram os servidores de Diablo I ou se me baniram da Battle.net mesmo u.u [/OFF]

Como nesse tempo eu já havia começado a programar, eu sabia que os stats, pontos de vida e mana estavam armazenados em variáveis e que o cheater, de alguma forma, alterava essas variáveis. Mas também não passou disso, pois muitos conceitos importantes ainda não me eram claros. Como um processo consegue “modificar” a memória de outro?

Então comecei a estudar o comportamento de outros cheaters, como o editor de saves de pokemon para gameboy, ou um executável modificado do jogo freecell que permitia mover qualquer carta para qualquer lugar. Cada um deles funcionando de uma forma diferente.

Aí, veio um amigão da escola e me convenceu de que eu só ia conseguir fazer esse tipo de coisa quando eu programasse fluentemente em Assembly e pudesse fazer qlq coisa em C. O que NÃO é verdade!!!

Depois disso, só voltei a me interessar pelo assunto uns 5 anos depois.
Em 2004 ou 2005 (não lembro) criei copiei e compilei um cheater em Visual Basic 6 para um MMORPG-modinha da época. Como eu apenas modifiquei alguns fontes que peguei na internet, não entendia completamente o que estava acontecendo. Ao ler artigos sobre o assunto e estudar o fonte, entendi que o código simplesmente modificava alguns dados que estavam armazenados na memória utilizada pelo jogo… há! é assim que aquele maldito bobafeet funcionava então!

Passou um tempo, o cheater já estava famoso aqui na minha cidade e muitas lan-houses passaram a usá-lo. Esses “bons jogadores” sempre pediam para adicionar algum feature, tipo que o cheater possa jogar sozinho enquanto ele vê um video educativo no www.***tube.com. Mas tudo bem, moleques de 12 anos não precisam saber a diferença entre cheater e bot. O final infeliz dessa história eu deixo pra outro post.

Com as atualizações constantes do jogo, eu tb precisava atualizar os endereços de memória modificados pelo cheater, então as coisas começaram a fazer mais sentido. Utilizava o ArtMoney pra escanear a memória do jogo e atualizava a lista de endereços, coisa simples. Nesse processo de escanear e procurar novos endereços, comecei a perceber que vários outros locais armazenavam informações úteis para futuras funções do cheater. E com toda a curiosidade que um programador deve ter, fucei em cada canto do jogo para descobrir mais sobre o funcionamento do mesmo.

E meu cheater?

Pra que serviu toda essa lengalenga? Pra deixar claro que não adianta copiar e compilar os códigos postados aqui. Talvez vc consiga fazer um cheater lecalzinho pra algum jogo, mas só isso. Pra aprender, vc PRECISA ter a curiosidade. A curiosidade matou o gato, mas ensinou ele a utilizar mto bem as outras 6 vidas.

Então, no próximo post vou tentar passar o pouco que sei sobre o tipo de cheater que eu considero mais fácil: os que editam a memória.

boost::asio – Introdução

Apesar de pouco comentado (pelo menos nos forums que eu participo participava), Boost é um conjunto de bibliotecas que facilitam muito a vida do programador e , sem dúvidas, é o plus-plus do C++. Se vc ainda não conhece: http://www.boost.org/.

Para quem não sabe, Boost.Asio é uma biblioteca multiplataforma (cross-platform) para programação de rede/comunicação (network) e operações de entrada e saída em baixo nível (low-level I/O) que oferece, aos desenvolvedores, um modelo consistente e assíncrono.

(Essa definição foi descaradamente traduzida da encontrada no site oficial)

Então, o que eu posso fazer com isso?

Você pode, por exemplo, usar sockets (TCP, UDP e ICMP), Timers e criar/manipular portas seriais.

Mas eu sei fazer isso! É só incluir o winsock.h e… no linux é fácil tb…

Não ter que se preocupar com o startup e cleanup do Winsock e não ter que colocar 8463763 #ifdef’s no meio do código já é um bom motivo para usar Boost.Asio. Se vc escrever “socket.read_some(…);“, vai funcionar em qualquer plataforma suportada (Win32/64, Linux kernel 2.4+, Solaris, Mac OS X 10.4+).

Beleza! Cadê os exemplos?

Antes disso, para não ficar perdido, é necessário entender como o Boost.Asio trabalha. Ao inves de oferecer um modelo genérico aproximado ao que há de comum entre as várias plataformas, a biblioteca apresenta uma nova proposta: para efetuar operações de entrada e saída seu programa precisa de, no mínimo, um objeto io_service (boost::asio::io_service). O objeto io_service funciona como um intermediário entre o seu software e o sistema operacional. Overhead? Tenha certeza que o boost faz esse intermédio da forma mais eficiente possível e, até hoje, nunca vi ninguém reclamando sobre o desempenho da biblioteca. A imagem abaixo (que foi retirada do site oficial) mostra o funcionamento do Boost.Asio para operações síncrona:

  1. O programa inicia a conexão chamando o objeto i/o (socket, por exemplo);
  2. O objeto i/o encaminha a requisição de conexão para o objeto io_service;
  3. O objeto io_service faz uma chamada ao sistema operacional para realizar a conexão;
  4. O sistema operacional retorna um resultado para o objeto io_service;
  5. O objeto io_service “traduz” qualquer erro resultante na operação e retorna ao objeto i/o; e
  6. O objeto i/o retorna o resultado para o programa.

O modelo para operações assíncronas é representado pelo diagrama ao lado:

Ao invés de esperar cada etapa do modelo síncrono, aqui podemos passar uma função handler que será chamada assim que a operação for concluída, independente da ocorrência de erros.

As três primeiras etapas são praticamente idênticas ao modelo anterior (do ponto de vista do usuário/programador):

  1. O programa inicia a conexão chamando o objeto i/o (socket, por exemplo);
  2. O objeto i/o encaminha a requisição de conexão para o objeto io_service; e
  3. O objeto io_service faz uma chamada ao sistema operacional para realizar a conexão;

Após as etapas indicadas, o sistema operacional indica o resultado da operação colocando-o em uma fila que será lida pelo objeto io_service, que por sua vez “traduz” qualquer mensagem de erro e chama a função handler passada como parâmetro pelo programa.

É importante comentar que, para que o objeto io_service possa tratar as tarefas/operações assíncronas pendentes, é necessário chamar io_service::run().

A função io_service::run() retornará assim que não houver mais tarefa assíncronas pendentes.

Okay! Então eu crio um objeto io_service e já era?

Aí é que está a grande maravilha do modelo proposto: usando vários objetos io_service (um em cada thread) e dividindo as operações entre eles, permitimos ao sistema operacional também dividí-las entre os vários núcleo disponíveis!

Tá… e os exemplos?

Timer

Para um wait síncrono (só retorna depois de completo):

#include <iostream>
#include <boost/asio.hpp>
 
using boost::asio::io_service;
using boost::asio::deadline_timer;
 
int main(int ac, char ** av)
{
    io_service ios;
    
    deadline_timer t(ios);
    t.expires_from_now(boost::posix_time::seconds(5));
    
    std::cout << "Esperando 5 segundos..." << std::endl;
    
    t.wait();
    
    std::cout << "Continua..." << std::endl;
    return 0;
}

Para um timer assíncrono, precisamos de um handler:

void handler(boost::system::error_code & ec)
{
    if(ec)
        //erro
    else
        //ok
}

Então, podemos usar o wait assíncrono:

t.expires_from_now(boost::posix_time::milliseconds(400));
t.async_wait(handler);
ios.run();

Um exemplo de timer assíncrono:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
 
using boost::asio::io_service;
using boost::asio::deadline_timer;
 
void handler(int segundo, boost::system::error_code & ec)
{
    if(!ec)
        std::cout << "Esperando... " << segundo << std::endl;
}
 
int main(int ac, char ** av)
{
    io_service ios;
 
    for(int i = 1; i <= 5; i++)
    {
        deadline_timer * t = new deadline_timer(ios);
        t->expires_from_now(boost::posix_time::seconds(i));
        t->async_wait(boost::bind(&handler, i, boost::asio::placeholders::error));
    }
 
    ios.run();
 
    std::cout << "Continua..." << std::endl;
    return 0;
}

Repare que não me preocupei em manter uma referência para os objetos criados dinamicamente (para apagá-los posteriormente), pois o programa é terminado logo após o retorno do último timer assíncrono.

Socket

Um exemplo simples de socket (tcp) que se conecta ao site:

#include <iostream>
#include <boost/asio.hpp>
 
using boost::asio::io_service;
using boost::asio::ip::tcp;
 
int main(int ac, char ** av)
{
    io_service ios;
    
    tcp::socket sck(ios);
    tcp::endpoint endp(boost::asio::ip::address::from_string("64.191.3.101"), 80);
    
    try
    {
        sck.connect(endp);
        std::cout << "Conectado!" << std::endl;
    }
    catch(boost::system::system_error & error)
    {
        std::cout << "Erro ao conectar: " << error.what() << std::endl;
    }
    
    std::cout << "Continua..." << std::endl;
    return 0;
}

Ou um resolver:

#include <iostream>
#include <boost/asio.hpp>
 
using boost::asio::io_service;
using boost::asio::ip::tcp;
 
int main(int ac, char ** av)
{
    io_service ios;
    
    tcp::resolver resolver(ios);
    tcp::resolver::query query("blog.delarco.com.br", "http");
    tcp::resolver::iterator iter = resolver.resolve(query);
    tcp::resolver::iterator end;
    
    while (iter != end)
    {
        tcp::endpoint endpoint = *iter++;
        std::cout << endpoint << std::endl;
    }
    
    return 0;
}

Como não parecer um idiota no Team Fortress 2

Recentemente adquiri, pelo Steam, o pacote Orange Box que inclui: Half-Life 2, HL2: Episode One, HL2: Episode Two, Portal e Team Fortress 2. Até então, meu interesse no pacote era a série HL2, pois sempre fui fã do Freeman. Portal eu já até tinha jogado (a versão 2D, em flash) e posso afirmar que, apesar de curto, é um ótimo jogo e um dos meus preferidos. E TF2? Até então só tinha ouvido falar em algum forum ou blog.

Ao terminar de baixar o pacote (muito dolorosamente com a minha conexão de 256 KB), nem sequer cheguei a testar TF2. Passado um mês, já havia terminado os outros 4 jogos e, na falta do que jogar, resolvi testar o TF2… e não é que ATÉ era legalzinho? Às vezes, quando não tinha mais nada para fazer, abria o jogo, pegava um pyro e saia atropelando (vai dizer que pyro não é a classe mais usada pelos newbies?). O resultado? Agora não consigo ficar mais de 24 horas sem jogar.

Pra quem joga, meu nickname está sempre como “keatoon” e é mais fácil me achar nos servers que tenham fast/instant respawn habilitados ;)

Enfim, pesquisando sobre o jogo, achei algumas dicas muito interessantes para quem está começando:

  • Antes de mais nada, TF2 é um jogo que DEVE ser jogado em equipe. Você pode até ser um antisocial e tentar jogar sozinho, mas a diversão e chance de vitória estão no team-play;
  • Por padrão, a tecla G está associada ao “taunt”. Mude para outra tecla, pois o G fica bem próximo às outras teclas que você usa (principalmente se vc for um spy e tentar usar a tecla B para voltar ao último disfarce);
  • Seja chato / irritante: mesmo se estiver jogando com pessoas que vc não conheça, encha o saco do seu time para que alguém mude para Medic, se não houver nenhum. Geralmente eu mesmo mudo de classe quando necessário, pois um payload com 5 snipers, 5 spies e nenhum médico é um jogo perdido. Como descrito acima, TF2 é um team-oriented game e se seu time não percebe que não há cooperação, encha o SACO MESMO! Se vc está no último control point e metade do seu time ainda é sniper, mude de servidor;
  • Vire-se, sempre! O único modo de levar um backstab é ficando de costas para o spy;
  • Mesmo se o seu objetivo no jogo é ser o top-fragger, capturar pontos e destruir buildings são mais importantes, em termos de cooperatividade, do que matar players do outro time;
  • Se estiver jogando com a classe Soldier, use a sua arma secundária quando o inimigo ainda estiver vivo após os 4 tiros do rocket launcher. Se vc for muito ruim de mira ou ainda não souber prever a movimentação dos outros players, atire no chão, pois o dano pela explosão não pode ser evitado.
  • Ainda como Soldier, evite atirar quatro vezes seguidas sem pausa, pois isso torna o seu ataque muito previsível e fácil de se esquivar. Então, ao invés de atirar assim: 1-2-3-4, faça combinações do tipo: 1-2—3–4. Se o inimigo tentar pular para se esquivar, ele vira um alvo fácil.
  • Tenha um time balanceado. Não há necessidade de ter 6 ou 7 players da mesma classe em um time. Cada classe tem suas fraquezas e cada uma completa a outra. Um engenheiro sem um pyro para fazer spycheck de tempos em tempos vira um alvo fácil para spies, por exemplo;
  • A sala de respawn (resuply) não serve apenas para isso. Vc também pode completar sua vida, munição e metal (no caso dos engenheiros). Na maioria das vezes é melhor gastar alguns segundos voltando à sala do que morrer e esperar o respawn;
  • Em alguns mapas, durante o setup (os 50 segundos antes do pelego) vc pode levar dano caso fique muito próximo aos portões e… é bem humilhante chato morrer antes mesmo do round começar ;)
  • Jogue pelo menos um round completo com cada classe. Além de render um achievement, vc aprende sobre as forças e fraquezas de cada uma, sabendo exatamente como combater cada uma delas;
  • Conheça os mapas. Com o tempo vc aprenderá sobre as diversas rotas de cada mapa, melhores lugares para colocar sentry gun’s, stickies etc;
  • Jogadores do seu time são “imateriais”. Se alguém bloquear a sua passagem, tenha certeza de que é um spy;
  • Scout’s contam como duas pessoas ao capturar pontos. Já vi um time inteiro de scout’s ganhar uma partida no mapa Steel em apenas alguns segundos;
« Older posts

© 2026 delarco

Theme by Anders NorenUp ↑