Eu sempre fiquei intrigado para saber como o sistema de Skins do launcher do CraftLandia funciona, não, não o sistema de enviar as skins, isto dai é simplesmente um POST, eu quero saber como o launcher do CraftLandia redireciona as requests de skins/capas para os servidores deles.

Então eu resolvi investigar um pouco isto para descobrir como o CraftLandia fez, ah, e se reclamar que eu estou ”decompilando”…

Annoying Dog

Annoying Dog

Eu estarei usando o MCFreedomLauncher como base.

Primeiramente, eu estarei analisando o launcher Minigames do CraftLandia, que, por algum motivo, ele é quase impossível de se achar, precisa clicar em vários links só para conseguir encontrar ele.

DíficilLandia

Download do Launcher: https://download.craftlandia.com.br/craftlandia.zip

Após você baixar, você irá se deparar com estes arquivos:

Sabia que todos eles são inúteis? O que a gente quer está dentro da pasta ”data\CraftLandia Minigames”

Agora vem a baianagem estilo CraftLandia que ama a 1.5.2.

Esse ”launcher.jar” não é um Launcher, é só um ”Loader”, sério, até o nome da única classe dentro dele se chama ”Loader”

Mas, se a gente olhar um pouco para baixo…

Nossa ”launcher.jar”, você vem sempre aqui?

Vamos mover esse Launcher para a alguma pasta para que a gente possa explorar ele melhor.

Agora, vamos jogar ele no Luyten para analisar ele melhor.

Isso sim que eu chamo de um Launcher.

Tá, mas cadê o sistema de patcheamento de JARs?

Calma cara, ainda nem começamos direito.

O sistema de patcheamento de JAR é um sistema bem simples, mas, é claro, que funciona, o sistema é mais ou menos assim:

Pré-inicialização do Minecraft:
    Pegar JAR da Profile
    Duplique a JAR, renomeie a duplicata para \"nome da versão_patched\"
    Fazer um loop em todas as classes
    Se a classe contém uma String específica, altere ela para a substituição desejada
    Salve todas as classes e remova o META-INF
    Renomeie a \"nome da versão_patched\" para \"nome_da_versao\"

Ok, agora que nós sabemos o que ele faz, agora nós podemos analisar como ele faz, e é um processo bastante simples até.

…mas, é claro, encontrar COMO começa o sistema é muito complicado, então eu usei o meu amigo Wireshark para encontrar da onde surge essas Skins do CraftLandia…

…após entrar no CraftLandia minigames, eu encontrei a seguinte URL: https://mcdata0.craftlandia.com.br/mcskins/Frog.png

Agora fica fácil, só jogar no Luyten para procurar esta URL e vlw flw, aí é só explorar, e foi isto que eu fiz :)

No net.minecraft.launcher, existe a classe LauncherConstants, lá fica todas as variáveis estásticas, o criador do Launcher resolveu \”aproveitar\” esta classe para adicionar a seguinte linha:

public static final String[][] PATCH_PATTERN = new String[][] { { "https://s3.amazonaws.com/MinecraftSkins/", "https://mcd0.craftlandia.com.br/mcskins/" }, { "https://s3.amazonaws.com/MinecraftCloaks/", "https://mcd0.craftlandia.com.br/mccloaks/" }, { "https://skins.minecraft.net/MinecraftSkins/", "https://mcdata0.craftlandia.com.br/mcskins/" }, { "https://skins.minecraft.net/MinecraftCloaks/", "https://mcdata0.craftlandia.com.br/mccloaks/" }};

Isto os ”patches” que deverão ser realizados em casa classe, se você não entendeu esse emaranhado de texto, é uma String[][], ou seja:

{ "Valor Original", "Valor Novo" }

Bem, enquanto parece ser bom na teoria, na realidade é muita confusão e vários erros, ou seja, eu decidi ignorar esse sistema baiano de patching para usar outro.

Aliás, se você percebeu, existem quatro URLs diferentes, até aí tudo bem, mas existem duas iguais, que só muda o subdomínio, bem, eu irei falar o porque disto após entrar na parte da class patching.

Para patchear a JAR, o CraftLandia usa duas classes:

  1. ZipPatcher, usado para rodar a ZIP e substituir as Strings.
  2. ByteUtil, usado para substituir as Strings sem afetar o resto da estrutura da classe.

Estas duas classes estão no craftlandia.patch

ZipPatcher.class

Como o sistema é um simples \”encontrar e substituir\”, a nova URL precisa ter o mesmo tamanho que a original, se for maior ou menor o Minecraft irá travar na hora de carregar a classe.

Ou seja, hora de analisar as URL!

https://s3.amazonaws.com/MinecraftSkins/ (39 caracteres)

https://mcd0.craftlandia.com.br/mcskins/ (39 caracteres)

https://s3.amazonaws.com/MinecraftCloaks/ (40 caracteres)

https://mcd0.craftlandia.com.br/mccloaks/ (40 caracteres)

https://skins.minecraft.net/MinecraftSkins/ (42 caracteres)

https://mcdata0.craftlandia.com.br/mcskins/ (42 caracteres)

https://skins.minecraft.net/MinecraftCloaks/ (43 caracteres)

https://mcdata0.craftlandia.com.br/mccloaks/ (43 caracteres)

Se nós analisarmos, 43 - 40 = 3, sabe o que mais tem 3? Illuminati.

Será que é uma conhecidência? Acho que não.

Isto prova que o CraftLandia é do Illuminati.

https://ichef.bbci.co.uk/news/ws/660/amz/worldservice/live/assets/images/2015/08/20/150820044619_illuminati_624x351_thinkstock.jpg

Ok, você percebeu que a URL original e a URL substituida tem o mesmo número de caracteres? Como eu disse anteriormente, se a URL original tivesse, por exemplo, 20 caracteres, e a URL nova tivesse 34, iria dar erro na hora de iniciar o Minecraft.

”noça mas da onde brota a jar patcheada”

Simples, meu caro amigo, ela é patcheada no MinecraftGameRunner

Não encontrou aonde é feito o patching ainda? Vou te ajudar um pouco…

Exatamente, sabe o que isto significa? Hora de entender o código.

patcher.patchZip(version, version_patched, LauncherConstants.PATCH_PATTERN, false);

Isto é o nosso amigo patchZip, ele é daora, ele sabe patchear as coisas.

Quando o Patcher é executado, a JAR *nome da versao*_patched é editada para adicionar as modificações das Skins.

Por algum motivo, o Launcher do CraftLandia não substitui a ”1.7.2.jar” pela ”1.7.2_patched.jar”, por isto eu precisei adicionar este código para copiar ela.

if (version_patched.exists()) {

    FileUtils.copyFile(version_patched, version);

}

Se você colocar isto, ele irá substituir a JAR original pela JAR modificada, fazendo o Minecraft iniciar corretamente com as nossas modificações!

Mas, por algum motivo, o ZipPatcher que eu… ”decompilei” estava muito bugado, muitas vezes falhava na hora de patchear a JAR, por isto eu modifiquei um pouco o ZipPatcher e fiz substituições hardcoded.

Se você perceber, eu também precisei fazer uma URL que tivesse o mesmo número de caracteres que a URL original:

https://frisk.sparklypower.net/AsrielSkins/

https://frisk.sparklypower.net/AsrielCloaks/

https://cd.sparklypower.net/AsrielSkins/

https://cd.sparklypower.net/AsrielCloaks/

Após juntar todos estes códigos toscos em algum negócio estilo Spagetthi, você consegue algo que funciona!

Papyrus

Recaptulando, é necessário editar o LauncherConstants, MinecraftGameRunner e adicionar duas novas classes, a ZipSigner e a ByteUtil, e é assim que o CraftLandia consegue fazer o sistema de skins deles! ;)

Ah, e é claro, não se esqueça de adicionar isto no seu código:

MinecraftGameRunner.LOGGER.info("( * O cachorro absorve a decompilação )");