Модификация клиента - osipxd/xLauncher-Reloaded GitHub Wiki

Первым делом нужно модифицировать клиент, чтобы заработала защита в реальном времени. Для редактирования файлов я советую использовать Notepad++

Подготовка клиента

Подготовка клиента с Forge несколько отличается от подготовки клиента без него.

Если установлен Forge

  1. Скачиваем нужную версию Forge-Src по этой ссылке.
  2. Извлекаем архив в удобное место и запускаем скрипт install. Ждем некоторое время.

Если Forge не установлен

  1. Для начала скачиваем чистый клиент Minecraft.
  2. Скачиваем MCP под свою версию клиента и распаковываем в удобное место.
  3. Копируем файлы клиента в папку /mcp/jars. Для версий ниже 1.6.х надо скопировать папку bin, для версий выше - папки assets, versions, libraries. ВНИМАНИЕ! В папке bin (или versions) должен лежать предварительно скачанный чистый клиент.
  4. Запускаем скрипт decompile и ждем декомпиляции клиента.
  5. В папку /mcp/src/minecraft извлекаем файлы из архива crypt.zip
  6. Редактируем файл /src/minecraft/net/minecraft/client/NetClientHandler.java: В самом начале добавляем импорты. Добавьте только те, которых не хватает!
import java.util.Random;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream
import java.net.InetAddress;
import java.net.Socket;;
import java.net.SocketTimeoutException;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import ru.xeroxp.server.utils.Base64;

После этого ищем функцию sendSessionRequest и заменяем ее на это (Внимание! Комментарии.):

    private static int symbolscount = 5; // Должен быть таким же как и в сокет-сервере
    private static byte[] key = {
            0x74, 0x68, 0x69, 0x73, 0x49, 0x73, 0x41, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79
    };
	
	private String sendSessionRequest(String par1Str, String par2Str, String par3Str) {
	try {
            SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
            // Тут менять ip порт сокет-сервера
            SSLSocket socket = (SSLSocket) sf.createSocket(InetAddress.getByName("localhost"), 4444);
            socket.setEnabledCipherSuites(socket.getSupportedCipherSuites());
            socket.startHandshake();
            socket.setSoTimeout(10000);
            DataInputStream in = new DataInputStream(socket.getInputStream());
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            out.writeUTF("s:" + encrypt(gensalt() + urlEncode(par1Str) + ":" + urlEncode(par2Str) + ":" + urlEncode(par3Str)));
            out.flush();
            String var6 = in.readUTF();
			socket.close();
			return var6;
        } catch (Exception var7) {
            return var7.toString();
        }
    }

    private static String encrypt(String strToEncrypt) {
        try
        {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            final SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            final String encryptedString = Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes()));
            return encryptedString;
        }
        catch (Exception e)
        {
            System.out.println("Error while encrypting: " + e);
        }
        return null;
    }

    private static String gensalt(){
        String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        Random rnd = new Random(); 
        char[] text = new char[symbolscount];
		
        for (int i = 0; i < symbolscount; i++) {
            text[i] = characters.charAt(rnd.nextInt(characters.length()));
        }
		
        return new String(text);
    }

Сохраняем файл.

Встраивание защиты

Эта операция одинакова как для клиентов с Forge, так и без него.

Открываем файл /src/minecraft/net/minecraft/Minecraft.java и добавляем в начало импорты:

import java.io.DataOutputStream;
import java.net.Socket;

Ищем функцию startGame и в конце её (перед знаком }), добавляем строку checkLauncherRunning();. Затем, после знака }, добавляем:

    private static void checkLauncherRunning() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Socket socket = new Socket("172.0.0.1", 6565); // Тут можно поменять порт для соединения с лаунчером
                    socket.setSoTimeout(0);
                    DataOutputStream out = new DataOutputStream(socket.getOutputStream());

                    while (true) {
                        if (!socket.isConnected() || socket.isClosed()) {
                            socket.close();
                            out.close();
                            System.exit(1);
                        }

                        out.writeUTF("I'm alive");
                        out.flush();
                        Thread.sleep(10000);
                    }
                } catch (Exception e) {
                    System.out.println("Launcher process doesn't exist");
                    System.exit(1);
                }
            }
        }).start();
    }

Пропатчивание своего клиента

  1. В папке /mcp (или /forge/mcp) запускаем скрипт recompile и после окончания его работы скрипт reobfuscate. Если вы все седлали правильно, то в консоли не должно возникнуть ошибок.

  2. Переходим в папку /reobf/minecraft и в ней видим файлы .class. Копируем их внутрь главного файла клиента (minecraft.jar или 1.6.2.jar и т. д.)

Модификация клиента завершена.