Ну чтож создаю уже 2-ую тему по AltManager,
хотелось бы спросить почему в AltManager не сохраняются ники Вот Код:
помогите я тупой, при перезаходе не сохраняются уже не знаю что делать
хотелось бы спросить почему в AltManager не сохраняются ники Вот Код:
Java:
package im.expensive.altmanager;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager;
import im.expensive.ui.mainmenu.MainScreen;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.font.Fonts;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.MainMenuScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Session;
import net.minecraft.util.text.StringTextComponent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.List;
public class AccountManagement extends Screen {
private static final Logger LOGGER = LogManager.getLogger();
private static final long DOUBLE_CLICK_INTERVAL = 250;
private static final int ACCOUNT_LIST_START_Y = 45;
private static final int ACCOUNT_LIST_ENTRY_HEIGHT = 20;
private static final int MAX_LIST_HEIGHT = 400;
private static final int LIST_WIDTH = 400;
private static final int BUTTON_WIDTH = 100;
private static final int BUTTON_HEIGHT = 20;
private static final int TEXT_FIELD_HEIGHT = 20;
private static final int COLOR_SELECTED = new Color(124, 124, 125, 255).getRGB();
private static final int COLOR_BACKGROUND = new Color(0, 0, 0, 255).getRGB();
private static final int COLOR_HIGHLIGHT = new Color(0, 0, 0, 100).getRGB();
private static final int COLOR_WHITE = 0xFFFFFF;
private static final int COLOR_GREEN = 0x00FF00;
private static final int COLOR_HINT = 0xCCCCCC;
private static final ResourceLocation STEVE_SKIN = new ResourceLocation("textures/entity/steve.png");
private static final String ACCOUNTS_FILE_PATH = "star/files/accounts.star";
private long lastClickTime = 0;
private boolean isScrolling = false;
private int lastMouseY = 0;
private int scrollOffset = 0;
private Button loginButton;
private Button deleteButton;
private static List<Account> filteredAccounts = new ArrayList<>();
private static final List<Account> accounts = new ArrayList<>();
private Account selectedAccount = null;
private static TextFieldWidget searchField;
private TextFieldWidget fieldWidget;
private int mouseY;
public AccountManagement() {
super(new StringTextComponent("Активный аккаунт"));
loadAccounts();
}
private static class Account {
String username;
Account(String username) {
this.username = username;
}
}
@Override
public void init() {
int centerX = this.width / 2;
int centerY = this.height / 2;
int listX = centerX - LIST_WIDTH / 2;
int searchFieldX = centerX - 100;
// Поисковое текстовое поле для фильтрации аккаунтов
searchField = new TextFieldWidget(font, searchFieldX, 20, 200, TEXT_FIELD_HEIGHT, new StringTextComponent(""));
searchField.setResponder(this::filterAccounts);
this.children.add(searchField);
//Текст-заполнитель для searchField
searchField.setSuggestion("");
int buttonY = this.height - 35;
int buttonSpacing = BUTTON_WIDTH + 5;
// Добавить кнопку для действий
loginButton = addButton(new Button(centerX - 2 * buttonSpacing , buttonY, BUTTON_WIDTH, BUTTON_HEIGHT, new StringTextComponent("Войти"), button -> loginSelectedAccount()));
deleteButton = addButton(new Button(centerX - buttonSpacing, buttonY, BUTTON_WIDTH, BUTTON_HEIGHT, new StringTextComponent("Удалить"), button -> deleteSelectedAccount()));
addButton(new Button(centerX, buttonY, BUTTON_WIDTH, BUTTON_HEIGHT, new StringTextComponent("Добавить аккаунт"), button -> Minecraft.getInstance().displayGuiScreen(new AddAccountScreen())));
addButton(new Button(centerX + buttonSpacing, buttonY, BUTTON_WIDTH, BUTTON_HEIGHT, new StringTextComponent("Выйти"), button -> Minecraft.getInstance().displayGuiScreen(new MainScreen())));
// Текстовое поле для ввода имени пользователя (скрыто по умолчанию)
fieldWidget = new TextFieldWidget(this.font, centerX - 150, 100, 300, TEXT_FIELD_HEIGHT, new StringTextComponent("Никнейм"));
fieldWidget.setVisible(false);
fieldWidget.setMaxStringLength(16);
this.children.add(fieldWidget);
// Изначально показывать все аккаунты
filteredAccounts = new ArrayList<>(accounts);
}
public void addAccount(String username) {
if (!isValidUsername(username)) {
LOGGER.warn("Попытка с недопустимым именем пользователя: " + username);
return;
}
for (Account account : accounts) {
if (account.username.equalsIgnoreCase(username)) {
LOGGER.warn("Попытка с дублирующимся именем пользователя: " + username);
return; // предотвратить добавление дубликатов имен пользователей
}
}
accounts.add(new Account(username));
saveAccounts();
}
@Override
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
this.renderBackground(matrixStack);
super.render(matrixStack, mouseX, mouseY, partialTicks);
float Width2 = 20.0f;
float height2 = 20.0f;
// renderBackgroundGradient(matrixStack);
loginButton.active = selectedAccount != null;
deleteButton.active = selectedAccount != null;
// Обновить подсказки кнопок
updateButtonTooltips(loginButton, deleteButton, mouseX);
String currentUsername = Minecraft.getInstance().getSession().getUsername();
Fonts.montserrat.drawCenteredText(matrixStack, "Аккаунт - " + currentUsername + "", 475, 5, ColorUtils.rgb(90, 150, 255), 10f);
//кнопки и тд
DisplayUtils.drawRoundedRect(280, 45, Width2 + 380, height2 + 380, 10,
ColorUtils.setAlpha(ColorUtils.rgb(0, 0, 0), 255));
int listWidth = LIST_WIDTH;
int listX = this.width / 2 - listWidth / 2;
int listY = ACCOUNT_LIST_START_Y;
int visibleAccounts = MAX_LIST_HEIGHT / ACCOUNT_LIST_ENTRY_HEIGHT;
int startIndex = scrollOffset / ACCOUNT_LIST_ENTRY_HEIGHT;
int endIndex = Math.min(filteredAccounts.size(), startIndex + visibleAccounts);
int maxRenderY = this.height - 35 - ACCOUNT_LIST_ENTRY_HEIGHT;
//Отрисовка фона списка аккаунтов
if (!filteredAccounts.isEmpty()) {
for (int i = startIndex; i < endIndex; i++) {
int entryY = listY + (i - startIndex) * ACCOUNT_LIST_ENTRY_HEIGHT - (scrollOffset % ACCOUNT_LIST_ENTRY_HEIGHT);
if (entryY + ACCOUNT_LIST_ENTRY_HEIGHT <= maxRenderY) {
Account account = filteredAccounts.get(i);
String accountName = account.username;
// Отрисовка выделения для выбранного аккаунта
if (selectedAccount != null && accountName.equals(selectedAccount.username)) {
DisplayUtils.drawRoundedRect(listX, entryY, Width2 + 380, height2, 5,
ColorUtils.setAlpha(ColorUtils.rgb(57, 63, 117), 200));
}
//Отрисовка иконки головы игрока
Minecraft.getInstance().getTextureManager().bindTexture(STEVE_SKIN);
GlStateManager.enableBlend();
drawScaledCustomSizeModalRect(listX + 7, entryY + 2, 8, 8, 8, 8, 16, 16, 64, 64);
GlStateManager.disableBlend();
//Отрисовка имени аккаунта с разным цветом для аккаунта текущей сессии
int textColor = accountName.equals(currentUsername) ? COLOR_GREEN : COLOR_WHITE;
drawString(matrixStack, font, accountName, listX + 26, entryY + 6, textColor);
}
//Отрисовка полосы прокрутки
if (filteredAccounts.size() > visibleAccounts) {
int scrollBarHeight = MAX_LIST_HEIGHT * visibleAccounts / filteredAccounts.size();
int scrollBarY = listY + (scrollOffset * (MAX_LIST_HEIGHT - scrollBarHeight)) / (filteredAccounts.size() * ACCOUNT_LIST_ENTRY_HEIGHT - MAX_LIST_HEIGHT);
fill(matrixStack, listX + listWidth + 2, scrollBarY, listX + listWidth + 6, scrollBarY + scrollBarHeight, COLOR_WHITE);
}
// Отрисовка выделения, если мышь находится над определенным аккаунтом
if (mouseX >= listX && mouseX < listX + listWidth && mouseY >= entryY && mouseY < entryY + ACCOUNT_LIST_ENTRY_HEIGHT) {
fill(matrixStack, listX + 2, entryY + 2, listX + 18, entryY + 18, COLOR_HIGHLIGHT);
}
}
} else {
String noAccountsText = "Аккаунт не найден!";
drawCenteredString(matrixStack, font, noAccountsText, this.width / 2, listY + 20, COLOR_WHITE);
}
//Отрисовка searchField и текста-заполнителя
searchField.render(matrixStack, mouseX, mouseY, partialTicks);
renderSearchFieldPlaceholder(matrixStack);
//Отрисовка textField виджета
if (fieldWidget.getVisible()) {
fieldWidget.render(matrixStack, mouseX, mouseY, partialTicks);
}
}
private void renderSearchFieldPlaceholder(MatrixStack matrixStack) {
String searchFieldText = "Поиск аккаунта";
int searchFieldX = this.width / 2 - this.font.getStringWidth(searchFieldText) / 2 - 60;
int searchFieldY = 26;
if (!searchField.isFocused() && searchField.getText().isEmpty()) {
this.font.drawString(matrixStack, searchFieldText, searchFieldX, searchFieldY, COLOR_HINT);
}
}
private void updateButtonTooltips(Button loginButton, Button deleteButton, int mouseX) {
if (loginButton != null) {
loginButton.setMessage(new StringTextComponent(selectedAccount != null ? "Войти" : "Войти"));
}
if (deleteButton != null) {
deleteButton.setMessage(new StringTextComponent(selectedAccount != null ? "Удалить" : "Удалить"));
}
if (mouseOverButton(loginButton, mouseX)) {
renderTooltip(new StringTextComponent("Войти в выбранный аккаунт"), mouseX, mouseY);
}
if (mouseOverButton(deleteButton, mouseX)) {
renderTooltip(new StringTextComponent("Удалить выбранный аккаунт"), mouseX, mouseY);
}
}
private void renderTooltip(StringTextComponent войтиВВыбранныйАккаунт, int mouseX, int mouseY) {
}
// Вспомогательный метод для проверки, находится ли мышь над кнопкой
private boolean mouseOverButton(Button button, int mouseX) {
return button != null && mouseX >= button.x && mouseX < button.x + button.getWidth() &&
mouseY >= button.y && mouseY < button.y + button.getHeightRealms();
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
int listWidth = LIST_WIDTH;
int listX = this.width / 2 - listWidth / 2;
int visibleAccounts = MAX_LIST_HEIGHT / ACCOUNT_LIST_ENTRY_HEIGHT;
int startIndex = scrollOffset / ACCOUNT_LIST_ENTRY_HEIGHT;
int endIndex = Math.min(filteredAccounts.size(), startIndex + visibleAccounts);
int maxRenderY = this.height - 35 - ACCOUNT_LIST_ENTRY_HEIGHT;
if (button == 0) { //Левая кнопка мыши
long currentTime = System.currentTimeMillis();
for (int i = startIndex; i < endIndex; i++) {
int entryY = ACCOUNT_LIST_START_Y + (i - startIndex) * ACCOUNT_LIST_ENTRY_HEIGHT - (scrollOffset % ACCOUNT_LIST_ENTRY_HEIGHT);
if (entryY + ACCOUNT_LIST_ENTRY_HEIGHT <= maxRenderY && mouseX >= listX && mouseX < listX + listWidth && mouseY >= entryY && mouseY < entryY + ACCOUNT_LIST_ENTRY_HEIGHT) {
selectedAccount = filteredAccounts.get(i);
if (currentTime - lastClickTime < DOUBLE_CLICK_INTERVAL) {
loginSelectedAccount();
}
lastClickTime = currentTime;
return true;
}
}
}
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
if (this.isScrolling) {
this.isScrolling = false;
return true;
}
return super.mouseReleased(mouseX, mouseY, button);
}
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
if (this.isScrolling) {
int deltaYInt = (int) mouseY - this.lastMouseY;
this.scrollOffset -= deltaYInt;
this.scrollOffset = Math.max(0, Math.min(this.scrollOffset, filteredAccounts.size() * ACCOUNT_LIST_ENTRY_HEIGHT - MAX_LIST_HEIGHT));
this.lastMouseY = (int) mouseY;
return true;
}
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
private void filterAccounts(String query) {
if (query.isEmpty()) {
filteredAccounts = new ArrayList<>(accounts);
} else {
filteredAccounts.clear();
for (Account account : accounts) {
if (account.username.toLowerCase().contains(query.toLowerCase())) {
filteredAccounts.add(account);
}
}
}
}
private void loginSelectedAccount() {
if (selectedAccount != null) {
Minecraft.getInstance().session = new Session(selectedAccount.username, "", "", "mojang");
}
}
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
if (isMouseOverScreen(mouseX, mouseY)) {
scrollOffset -= (int) delta * ACCOUNT_LIST_ENTRY_HEIGHT;
int maxScroll = Math.max(0, filteredAccounts.size() * ACCOUNT_LIST_ENTRY_HEIGHT - MAX_LIST_HEIGHT);
scrollOffset = Math.max(0, Math.min(scrollOffset, maxScroll));
return true;
}
return super.mouseScrolled(mouseX, mouseY, delta);
}
private boolean isMouseOverScreen(double mouseX, double mouseY) {
int listWidth = LIST_WIDTH;
int listX = this.width / 2 - listWidth / 2;
int listY = ACCOUNT_LIST_START_Y;
return mouseX >= listX && mouseX < listX + listWidth && mouseY >= listY && mouseY < listY + MAX_LIST_HEIGHT;
}
private void deleteSelectedAccount() {
if (selectedAccount != null) {
// Видаляємо з основного списку
accounts.removeIf(account -> account.username.equals(selectedAccount.username));
// Видаляємо з відфільтрованого списку
filteredAccounts.removeIf(account -> account.username.equals(selectedAccount.username));
saveAccounts();
selectedAccount = null;
}
}
// Проверить, является ли имя пользователя допустимым
private boolean isValidUsername(String username) {
if (username == null || username.length() < 3 || username.length() > 16) {
return false;
}
return username.matches("[a-zA-Z0-9-_]+");
}
// Сохранить аккаунты в файл
private void saveAccounts() {
try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(Paths.get(ACCOUNTS_FILE_PATH)))) {
Set<String> uniqueUsernames = new HashSet<>();
for (Account account : accounts) {
if (uniqueUsernames.add(account.username.toLowerCase()) && isValidUsername(account.username)) {
out.println(account.username);
}
}
} catch (IOException e) {
LOGGER.error("Не удалось сохранить аккаунты", e);
}
}
// Загрузить аккаунты из файла
private void loadAccounts() {
File file = new File(ACCOUNTS_FILE_PATH);
if (file.exists()) {
try (Scanner scanner = new Scanner(file)) {
accounts.clear();
Set<String> uniqueUsernames = new HashSet<>();
while (scanner.hasNextLine()) {
String username = scanner.nextLine();
if (uniqueUsernames.add(username.toLowerCase()) && isValidUsername(username)) {
accounts.add(new Account(username));
}
}
} catch (IOException e) {
LOGGER.error("Не удалось загрузить аккаунты", e);
}
}
if (searchField != null) {
filterAccounts(searchField.getText());
}
}
/*
private void renderBackgroundGradient(MatrixStack matrixStack) {
DisplayUtils.drawRect(0, 0, width, height, ColorUtils.rgb(5, 10, 25));
DisplayUtils.drawRect(0, 0, width, height, ColorUtils.setAlpha(ColorUtils.rgb(0, 0, 0), 120));
}
*/
@Override
public void onClose() {
saveAccounts();
super.onClose();
}
}
Код:
помогите я тупой, при перезаходе не сохраняются уже не знаю что делать