Запасайтесь чипсами, ведь если вы пастер, то вы здесь на долго.
Специально для новичков
каждый блок был обозначен, если вам не знакомы некоторые слова советую почитать о них
в интернете.
видео с игрой с лоудера
Создаем новый проект с использованием
java 17 если у вас
чит экспенсив/экселлент и т.д.
1. Создание приложения с инициализацией всего необходимого.
После создание проекта вам нужно добавить в ваш
Main класс всю основу
package loader.starter;
import loader.objects.SettingObject;
import loader.objects.SquareObject;
import javax.swing.*;
import java.awt.*;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
public class Main {
/**
* Главный класс
* Добавление классов
*/
public static void main(String[] args) {
ImageIcon icon = new ImageIcon(Main.class.getResource("/loader/assets/logo.png"));
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Loader");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setIconImage(icon.getImage());
frame.setSize(707, 509);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
JPanel parentPanel = new JPanel(new CardLayout());
CardLayout cardLayout = (CardLayout) parentPanel.getLayout();
SquareObject mainPanel = new SquareObject(cardLayout, parentPanel);
SettingObject settingsPanel = new SettingObject(cardLayout, parentPanel);
parentPanel.add(mainPanel, "mainPanel");
parentPanel.add(settingsPanel, "settingsPanel");
frame.add(parentPanel);
frame.setVisible(true);
});
}
}
2. Создание рендера/конструкторов
Для начала нужно создать класс с цветами которые мы будем использовать, чтобы каждый раз
не искать нужный цвет.
package loader.utils;
import javax.swing.*;
import java.awt.*;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Класс, содержащий все цвета которые можно заюзать
*/
public class ColorUtil extends JPanel {
public static Color background = new Color(45, 45, 45);
public static Color headerColor = new Color(29, 29, 31);
public static Color buttonColor1 = new Color(66, 91, 129);
public static Color buttonColor2 = new Color(14, 93, 213);
}
Объект рендера главного меню
package loader.objects;
import loader.objects.buttons.StartButton;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Класс от части всего рендера
*/
public class SquareObject extends JPanel {
private StartButton startButton;
private ImageIcon settingsIcon;
private CardLayout cardLayout;
private JPanel parentPanel;
private boolean isRunning = false;
private boolean isHovered = false;
/**
* Конструктор инициализирует главное меню с кнопкой запуска и иконкой настроек
*
* @param cardLayout макет для переключения меню
* @param parentPanel панель для переключения
*/
public SquareObject(CardLayout cardLayout, JPanel parentPanel) {
this.cardLayout = cardLayout;
this.parentPanel = parentPanel;
/**
* Рендер заднего фона
*/
setBackground(ColorUtil.background);
setLayout(null);
/**
* Рендер кнопки "Запустить"
*/
startButton = new StartButton("Запустить");
startButton.setBackground(ColorUtil.buttonColor1);
startButton.setForeground(Color.WHITE);
startButton.setFont(new Font("Arial", Font.BOLD, 20));
startButton.setPreferredSize(new Dimension(200, 50));
startButton.setBounds((707 - 200) / 2, (509 - 50) / 2 + 50, 200, 50);
add(startButton);
startButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!isRunning) {
startButton.setBackground(Color.GREEN);
startButton.setText("Ожидайте");
/**
* Запуск майнкрафт в отдельном потоке
*/
new Thread(() -> {
loader.starter.Start.main(new String[]{});
}).start();
isRunning = true;
/**
* Закрытие лоудера через минуту
* Можете поменять значение как вам угодно
*/
Timer timer = new Timer(60000, evt -> {
Window window = SwingUtilities.getWindowAncestor(SquareObject.this);
if (window != null) {
window.dispose();
}
});
timer.setRepeats(false);
timer.start();
}
}
@Override
public void mouseEntered(MouseEvent e) {
isHovered = true;
updateButtonAppearance();
}
@Override
public void mouseExited(MouseEvent e) {
isHovered = false;
updateButtonAppearance();
}
});
settingsIcon = new ImageIcon(SquareObject.class.getResource("/loader/assets/setting.png"));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int iconX = getWidth() - 50;
int iconY = 4;
int iconWidth = 47;
int iconHeight = 43;
if (e.getX() >= iconX && e.getX() <= iconX + iconWidth && e.getY() >= iconY && e.getY() <= iconY + iconHeight) {
SwingUtilities.invokeLater(() -> cardLayout.show(parentPanel, "settingsPanel"));
}
}
});
}
/**
* Отрисовка компонентов
*
* @param g объект Graphics для защиты
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/**
* Рендер полосы сверху
*/
g.setColor(ColorUtil.headerColor);
g.fillRect(0, 0, getWidth(), 50);
/**
* Рендер текста
*/
String versionText = "v1.0";
String text = "Minecraft Loader";
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 40));
FontMetrics titleMetrics = g.getFontMetrics(g.getFont());
int titleX = (getWidth() - titleMetrics.stringWidth(text)) / 2 + 15;
int titleY = titleMetrics.getHeight() - 6;
g.drawString(text, titleX, titleY);
g.setFont(new Font("Arial", Font.BOLD, 20));
FontMetrics metrics = g.getFontMetrics(g.getFont());
int x = getWidth() - metrics.stringWidth(versionText) - 10;
int y = getHeight() - metrics.getHeight() + metrics.getAscent() - 10;
g.drawString(versionText, x, y);
if (settingsIcon != null) {
int iconX = getWidth() - 50;
int iconY = 4;
g.drawImage(settingsIcon.getImage(), iconX, iconY, 47, 43, this);
}
}
private void updateButtonAppearance() {
if (isRunning) {
startButton.setBackground(Color.GREEN);
startButton.setText("Ожидайте");
} else {
if (isHovered) {
startButton.setBackground(ColorUtil.buttonColor2);
} else {
startButton.setBackground(ColorUtil.buttonColor1);
}
}
}
}
Создание класса объекта меню настроек
package loader.objects;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URI;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Объект настроек с возможностью возврата к главному меню
*/
public class SettingObject extends JPanel {
private CardLayout cardLayout;
private JPanel parentPanel;
private int clickableTextX = 20;
private int clickableTextY = 150;
private int clickableTextWidth = 300;
private int clickableTextHeight = 20;
/**
* Отрисовка меню
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/**
* Рендер фона и элементов интерфейса
*/
setBackground(ColorUtil.background);
setLayout(null);
g.setColor(ColorUtil.headerColor);
g.fillRect(0, 0, getWidth(), 50);
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.PLAIN, 20));
int textX = 20;
int textY = 100;
g.drawString("Информация", textX, textY);
g.drawString("Данный лоудер просто прототип", textX, textY + 30);
g.drawString("Вы можете наложить свою обфускацию по желанию", textX, textY + 60);
FontMetrics fm = g.getFontMetrics();
String clickableText = "Ссылка на канал Tense client";
int textWidth = fm.stringWidth(clickableText);
g.setColor(Color.WHITE);
g.drawString(clickableText, clickableTextX, clickableTextY + 35);
Rectangle clickableArea = new Rectangle(clickableTextX, clickableTextY - fm.getAscent() + 35, textWidth, fm.getHeight());
addClickableArea(clickableArea);
}
/**
* Добавляет область кликабельной зоны
*
* @param clickableArea кликабельная область
*/
private void addClickableArea(Rectangle clickableArea) {
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (clickableArea.contains(e.getPoint())) {
openBrowser("https://www.youtube.com/@rarchik/videos");
}
}
});
}
/**
* Открывает браузер с указанной ссылкой
*
* @param url URL для открытия в браузере
*/
private void openBrowser(String url) {
try {
Desktop.getDesktop().browse(new URI(url));
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Конструктор кнопки возврата
*
* @param cardLayout макет для переключения панелей
* @param parentPanel панель для переключения
*/
public SettingObject(CardLayout cardLayout, JPanel parentPanel) {
this.cardLayout = cardLayout;
this.parentPanel = parentPanel;
JLabel backButton = new JLabel(new ImageIcon(SettingObject.class.getResource("/loader/assets/back_arrow.png")));
backButton.setBounds(10, 10, 100, 100);
backButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(() -> cardLayout.show(parentPanel, "mainPanel"));
}
});
add(backButton);
JLabel settingsLabel = new JLabel("Настройки", SwingConstants.CENTER);
settingsLabel.setFont(new Font("Arial", Font.BOLD, 40));
settingsLabel.setForeground(Color.WHITE);
settingsLabel.setBounds(0, 50, getWidth(), 50);
add(settingsLabel);
}
}
Класс кнопки старта
package loader.objects.buttons;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Добавление кнопки "Запуск"
*/
public class StartButton extends JButton {
public StartButton(String text) {
super(text);
setContentAreaFilled(false);
setFocusPainted(false);
/**
* Установка стандартных цветов фона и текста
*/
setBackground(ColorUtil.buttonColor1);
setForeground(Color.WHITE);
/**
* Обработчик событий мыши для эффекта наведения
*/
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
setBackground(ColorUtil.buttonColor2);
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(ColorUtil.buttonColor1);
}
});
/**
* Установка шрифта для текста кнопки
*/
setFont(new Font("Arial", Font.BOLD, 20));
}
/**
* Кастомное рисование компонента кнопки
*
* @param g объект Graphics для защиты
*/
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(getBackground());
g2.fill(new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), 30, 30));
super.paintComponent(g2);
g2.dispose();
}
/**
* Обновление свойств кнопки
*/
@Override
public void updateUI() {
super.updateUI();
setOpaque(false);
setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
}
}
package loader.starter;
import java.util.Arrays;
import net.minecraft.client.main.Main;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
public class Start
{
public static void main(String[] args)
{
String assets = System.getenv().containsKey("assetDirectory") ? System.getenv("assetDirectory") : "assets";
Main.main(concat(new String[] {"--version", "mcp", "--accessToken", "0", "--assetsDir", assets, "--assetIndex", "1.16", "--userProperties", "{}"}, args));
}
public static <T> T[] concat(T[] first, T[] second)
{
T[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
}
3. Нужно создать папку с ресурсами
(png)
Можете сделать как у меня
Посмотреть вложение 280336
Дальше обязательно
нужно сделать манифест чтобы лоудер можно было запускать как
исполняемый файл
Посмотреть вложение 280338
Manifest-Version: 1.0
Can-Retransform-Classes: true
Main-Class: loader.starter.Main
SplashScreen-Image: l.png
Дальше нужно создать директорию где будет
хранится ваш чит. У меня это будет здесь (Не забудьте про
нативки)
Посмотреть вложение 280339
Дальше использую imgur так как на форуме лимит загрузки изображений
Нужно добавить вашу
джарку в библиотеку
Теперь осталось
забилдить проект. Заходим в
Создаем новый
Дальше можно выбрать название с каким названием будет сохранятся ваша джарка
(НЕ ОБЯЗАТЕЛЬНО)
И делаем как на
Важно: С какой джавы вы билдили проект с такой джавы и нужно запускать джарку
Сохраняем,
Build - Build Artifacts и выбираем наш артифакт
После билда можете запускать ваш лоудер.
Так же не пишите мне за ассетсы майнкрафта, к примеру в Экселленте ассесты грузятся из диска C, а добавить их самостоятельно вы и сами сможете.
Я вам не скинул целый уже готовый проект чтобы вы поняли как это делать. Удачи. Так же вы должны учесть, что это не протект лоудер. Здесь нету проверки хвида и т.д. Систему хвида сделать не сложно, поэтому используйте лоудер как хотите