Начинающий
- Статус
- Онлайн
- Регистрация
- 6 Июн 2024
- Сообщения
- 39
- Реакции
- 0
- Выберите загрузчик игры
- Прочие моды
NotificationWidget:
package killse.dest.client.ui.widget.overlay;
// пишите если нужны еще какие то классы
import lombok.Getter;
import net.minecraft.client.util.math.MatrixStack;
import killse.dest.api.utils.animation.AnimationUtil;
import killse.dest.api.utils.animation.Easing;
import killse.dest.api.utils.color.UIColors;
import killse.dest.api.utils.render.RenderUtil;
import killse.dest.api.utils.render.fonts.Font;
import killse.dest.api.utils.render.fonts.Fonts;
import killse.dest.api.database.NotificationManager;
import killse.dest.client.features.modules.combat.AuraModule;
import killse.dest.client.ui.widget.Widget;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.time.Duration;
public class NotificationWidget extends Widget {
@Override
public String getName() {
return "Notifications";
}
public NotificationWidget() {
super(200f, 100f);
NotificationManager.getInstance().initialize();
}
@Getter
private static NotificationWidget instance;
public static void setInstance(NotificationWidget instance) {
NotificationWidget.instance = instance;
}
private final List<Notification> notifications = new ArrayList<>();
private Font iconFont;
private Font textFont;
private Font getIconFont() {
if (iconFont == null && mc != null && mc.getResourceManager() != null) {
iconFont = Fonts.ICONS;
}
return iconFont != null ? iconFont : Fonts.SF_MEDIUM;
}
private Font getTextFont() {
if (textFont == null && mc != null && mc.getResourceManager() != null) {
textFont = Fonts.SF_MEDIUM;
}
return textFont != null ? textFont : Fonts.SF_MEDIUM;
}
@Override
public void render(MatrixStack matrixStack) {
if (mc == null || mc.getResourceManager() == null) {
return;
}
float x = getDraggable().getX();
float y = getDraggable().getY();
float maxWidth = 180f;
updateNotifications();
float currentY = y;
for (int i = notifications.size() - 1; i >= 0; i--) {
Notification notification = notifications.get(i);
if (notification.animation.getValue() <= 0.01f) {
notifications.remove(i);
continue;
}
currentY = renderNotification(matrixStack, x, currentY, notification, maxWidth);
}
}
private float renderNotification(MatrixStack matrixStack, float x, float y, Notification notification, float maxWidth) {
float anim = (float) notification.animation.getValue();
float fontSize = scaled(6.5f);
float iconSize = fontSize + 2f;
float gap = scaled(4f);
float padding = scaled(6f);
String icon = notification.type.getIcon();
float iconWidth = getIconFont().getWidth(icon, iconSize);
String text = notification.text;
float textWidth = getTextFont().getWidth(text, fontSize);
float contentWidth = Math.min(textWidth + iconWidth + gap + padding * 2, maxWidth);
float contentHeight = fontSize + padding * 2;
float round = contentHeight * 0.3f;
float slideOffset = (1f - anim) * 20f;
float alpha = anim;
Color bgColor = new Color(12, 12, 18, (int)(200 * alpha));
RenderUtil.BLUR_RECT.draw(matrixStack, x + slideOffset, y, contentWidth, contentHeight, round, bgColor);
Color iconColor = notification.type.getColor();
iconColor = new Color(iconColor.getRed(), iconColor.getGreen(), iconColor.getBlue(), (int)(255 * alpha));
getIconFont().drawText(matrixStack, icon, x + padding + slideOffset, y + padding, iconSize, iconColor);
Color textColor = UIColors.textColor((int)(255 * alpha));
getTextFont().drawText(matrixStack, text, x + padding + iconWidth + gap + slideOffset, y + padding, fontSize, textColor);
getDraggable().setWidth(contentWidth);
getDraggable().setHeight(contentHeight);
return y + contentHeight + scaled(3f);
}
private void updateNotifications() {
NotificationManager.getInstance().cleanupExpiredNotifications();
List<NotificationManager.NotificationData> activeNotifications = NotificationManager.getInstance().getActiveNotifications();
for (Notification notification : notifications) {
notification.animation.update();
if (notification.displayTime > 0) {
notification.displayTime--;
if (notification.displayTime == 0) {
notification.animation.run(0.0, 500, Easing.SINE_OUT);
}
}
}
notifications.removeIf(n -> !activeNotifications.stream()
.anyMatch(active -> active.getText().equals(n.text) && active.getType().name().equals(n.type.name())));
}
public void addNotification(String text, NotificationType type) {
NotificationManager.getInstance().addNotification(text, NotificationManager.NotificationType.valueOf(type.name()));
Notification notification = new Notification(text, type);
notifications.add(notification);
notification.animation.setValue(0.0);
notification.animation.run(1.0, 300, Easing.SINE_OUT);
notification.displayTime = 60 * 3;
}
public static void notify(String text, NotificationType type) {
if (instance != null) {
instance.addNotification(text, type);
}
NotificationManager.getInstance().addNotification(text, NotificationManager.NotificationType.valueOf(type.name()));
}
public static class Notification {
private final String text;
private final NotificationType type;
private final AnimationUtil animation = new AnimationUtil();
private int displayTime = -1;
public Notification(String text, NotificationType type) {
this.text = text;
this.type = type;
}
}
public enum NotificationType {
AURA("A", new Color(255, 100, 100)),
SUCCESS("✓", new Color(100, 255, 100)),
WARNING("!", new Color(255, 200, 100)),
INFO("i", new Color(100, 200, 255)),
ERROR("✕", new Color(255, 100, 100));
private final String icon;
private final Color color;
NotificationType(String icon, Color color) {
this.icon = icon;
this.color = color;
}
public String getIcon() {
return icon;
}
public Color getColor() {
return color;
}
}
}
NotificationEntity:
package killse.dest.api.database.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.awt.*;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NotificationEntity {
private Long id;
private String text;
private String type;
private String icon;
private int colorR;
private int colorG;
private int colorB;
private boolean read;
private LocalDateTime createdAt;
private LocalDateTime expiresAt;
private int displayTime;
private String userId;
public NotificationEntity(String text, NotificationType type, int displayTime, String userId) {
this.text = text;
this.type = type.name();
this.icon = type.getIcon();
this.colorR = type.getColor().getRed();
this.colorG = type.getColor().getGreen();
this.colorB = type.getColor().getBlue();
this.read = false;
this.createdAt = LocalDateTime.now();
this.displayTime = displayTime;
this.userId = userId;
this.expiresAt = displayTime > 0 ? LocalDateTime.now().plusSeconds(displayTime / 20) : null;
}
public Color getColor() {
return new Color(colorR, colorG, colorB);
}
public void setColor(Color color) {
this.colorR = color.getRed();
this.colorG = color.getGreen();
this.colorB = color.getBlue();
}
public NotificationType getNotificationType() {
return NotificationType.valueOf(type);
}
public void setNotificationType(NotificationType type) {
this.type = type.name();
this.icon = type.getIcon();
setColor(type.getColor());
}
public enum NotificationType {
AURA("A", new Color(255, 100, 100)),
SUCCESS("✓", new Color(100, 255, 100)),
WARNING("!", new Color(255, 200, 100)),
INFO("i", new Color(100, 200, 255)),
ERROR("✕", new Color(255, 100, 100));
private final String icon;
private final Color color;
NotificationType(String icon, Color color) {
this.icon = icon;
this.color = color;
}
public String getIcon() {
return icon;
}
public Color getColor() {
return color;
}
}
}
NotificationManager:
package killse.dest.api.database;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import lombok.Getter;
import lombok.experimental.UtilityClass;
import killse.dest.api.system.backend.ClientInfo;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
public class NotificationManager {
@Getter
private static final NotificationManager instance = new NotificationManager();
private static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())
.registerTypeAdapter(Color.class, new ColorAdapter())
.setPrettyPrinting()
.create();
private static final Path DATABASE_PATH = Paths.get(ClientInfo.CONFIG_PATH_MAIN, "notifications.json");
private final List<NotificationData> notifications = new CopyOnWriteArrayList<>();
private final List<NotificationData> activeNotifications = new CopyOnWriteArrayList<>();
private NotificationManager() {
}
public enum NotificationType {
AURA("A", new Color(255, 100, 100)),
SUCCESS("✓", new Color(100, 255, 100)),
WARNING("!", new Color(255, 200, 100)),
INFO("i", new Color(100, 200, 255)),
ERROR("✕", new Color(255, 100, 100));
private final String icon;
private final Color color;
NotificationType(String icon, Color color) {
this.icon = icon;
this.color = color;
}
public String getIcon() { return icon; }
public Color getColor() { return color; }
}
public static class NotificationData {
private Long id;
private String text;
private NotificationType type;
private boolean read;
private LocalDateTime createdAt;
private LocalDateTime expiresAt;
private int displayTime;
private String userId;
public NotificationData() {}
public NotificationData(String text, NotificationType type, int displayTime, String userId) {
this.id = System.currentTimeMillis();
this.text = text;
this.type = type;
this.read = false;
this.createdAt = LocalDateTime.now();
this.displayTime = displayTime;
this.userId = userId;
this.expiresAt = displayTime > 0 ? LocalDateTime.now().plusSeconds(displayTime / 20) : null;
}
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public NotificationType getType() { return type; }
public void setType(NotificationType type) { this.type = type; }
public boolean isRead() { return read; }
public void setRead(boolean read) { this.read = read; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public LocalDateTime getExpiresAt() { return expiresAt; }
public void setExpiresAt(LocalDateTime expiresAt) { this.expiresAt = expiresAt; }
public int getDisplayTime() { return displayTime; }
public void setDisplayTime(int displayTime) { this.displayTime = displayTime; }
public String getUserId() { return userId; }
public void setUserId(String userId) { this.userId = userId; }
public boolean isExpired() {
return expiresAt != null && LocalDateTime.now().isAfter(expiresAt);
}
}
private static class LocalDateTimeAdapter implements JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
@Override
public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(FORMATTER.format(src));
}
@Override
public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
return LocalDateTime.parse(json.getAsString(), FORMATTER);
}
}
private static class ColorAdapter implements JsonSerializer<Color>, JsonDeserializer<Color> {
@Override
public JsonElement serialize(Color src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject obj = new JsonObject();
obj.addProperty("r", src.getRed());
obj.addProperty("g", src.getGreen());
obj.addProperty("b", src.getBlue());
obj.addProperty("a", src.getAlpha());
return obj;
}
@Override
public Color deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
JsonObject obj = json.getAsJsonObject();
return new Color(
obj.get("r").getAsInt(),
obj.get("g").getAsInt(),
obj.get("b").getAsInt(),
obj.has("a") ? obj.get("a").getAsInt() : 255
);
}
}
public void initialize() {
loadNotifications();
cleanupExpiredNotifications();
}
public void addNotification(String text, NotificationType type) {
addNotification(text, type, 60 * 3, "default");
}
public void addNotification(String text, NotificationType type, int displayTime) {
addNotification(text, type, displayTime, "default");
}
public void addNotification(String text, NotificationType type, int displayTime, String userId) {
NotificationData notification = new NotificationData(text, type, displayTime, userId);
notifications.add(notification);
activeNotifications.add(notification);
saveNotifications();
}
public List<NotificationData> getActiveNotifications() {
return new ArrayList<>(activeNotifications);
}
public List<NotificationData> getAllNotifications() {
return new ArrayList<>(notifications);
}
public List<NotificationData> getNotificationsByUser(String userId) {
return notifications.stream()
.filter(n -> userId.equals(n.getUserId()))
.collect(Collectors.toList());
}
public List<NotificationData> getUnreadNotifications() {
return notifications.stream()
.filter(n -> !n.isRead())
.collect(Collectors.toList());
}
public List<NotificationData> getUnreadNotificationsByUser(String userId) {
return notifications.stream()
.filter(n -> !n.isRead() && userId.equals(n.getUserId()))
.collect(Collectors.toList());
}
public void markAsRead(Long notificationId) {
notifications.stream()
.filter(n -> n.getId().equals(notificationId))
.findFirst()
.ifPresent(n -> {
n.setRead(true);
saveNotifications();
});
}
public void markAllAsRead() {
notifications.forEach(n -> n.setRead(true));
saveNotifications();
}
public void markAllAsReadForUser(String userId) {
notifications.stream()
.filter(n -> userId.equals(n.getUserId()))
.forEach(n -> n.setRead(true));
saveNotifications();
}
public void removeNotification(Long notificationId) {
notifications.removeIf(n -> n.getId().equals(notificationId));
activeNotifications.removeIf(n -> n.getId().equals(notificationId));
saveNotifications();
}
public void clearActiveNotifications() {
activeNotifications.clear();
}
public void clearAllNotifications() {
notifications.clear();
activeNotifications.clear();
saveNotifications();
}
public void clearNotificationsByUser(String userId) {
notifications.removeIf(n -> userId.equals(n.getUserId()));
activeNotifications.removeIf(n -> userId.equals(n.getUserId()));
saveNotifications();
}
public void cleanupExpiredNotifications() {
notifications.removeIf(NotificationData::isExpired);
activeNotifications.removeIf(NotificationData::isExpired);
saveNotifications();
}
public int getUnreadCount() {
return (int) notifications.stream().filter(n -> !n.isRead()).count();
}
public int getUnreadCountForUser(String userId) {
return (int) notifications.stream()
.filter(n -> !n.isRead() && userId.equals(n.getUserId()))
.count();
}
public NotificationData getNotificationById(Long id) {
return notifications.stream()
.filter(n -> n.getId().equals(id))
.findFirst()
.orElse(null);
}
public void updateNotification(Long id, String newText, NotificationType newType) {
notifications.stream()
.filter(n -> n.getId().equals(id))
.findFirst()
.ifPresent(n -> {
n.setText(newText);
n.setType(newType);
saveNotifications();
});
}
private void loadNotifications() {
try {
if (Files.exists(DATABASE_PATH)) {
String content = Files.readString(DATABASE_PATH);
Type listType = new TypeToken<List<NotificationData>>(){}.getType();
List<NotificationData> loaded = GSON.fromJson(content, listType);
if (loaded != null) {
notifications.clear();
notifications.addAll(loaded);
activeNotifications.clear();
activeNotifications.addAll(notifications.stream()
.filter(n -> !n.isExpired())
.collect(Collectors.toList()));
}
}
} catch (IOException e) {
System.err.println("Failed to load notifications: " + e.getMessage());
}
}
private void saveNotifications() {
try {
File parentDir = DATABASE_PATH.getParent().toFile();
if (!parentDir.exists()) {
parentDir.mkdirs();
}
String json = GSON.toJson(notifications);
Files.writeString(DATABASE_PATH, json);
} catch (IOException e) {
System.err.println("Failed to save notifications: " + e.getMessage());
}
}
public void exportToFile(String filePath) {
try {
String json = GSON.toJson(notifications);
Files.writeString(Paths.get(filePath), json);
} catch (IOException e) {
System.err.println("Failed to export notifications: " + e.getMessage());
}
}
public void importFromFile(String filePath) {
try {
String content = Files.readString(Paths.get(filePath));
Type listType = new TypeToken<List<NotificationData>>(){}.getType();
List<NotificationData> imported = GSON.fromJson(content, listType);
if (imported != null) {
notifications.addAll(imported);
saveNotifications();
}
} catch (IOException e) {
System.err.println("Failed to import notifications: " + e.getMessage());
}
}
}
Вложения
Последнее редактирование: