Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id 'fabric-loom' version '1.11-SNAPSHOT'
id 'fabric-loom' version '1.14-SNAPSHOT'
id 'maven-publish'
}

Expand Down Expand Up @@ -43,7 +43,7 @@ repositories {
dependencies {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
mappings loom.officialMojangMappings()
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"

modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
Expand Down
12 changes: 6 additions & 6 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://modmuss50.me/fabric.html
minecraft_version=1.21.10
yarn_mappings=1.21.10+build.1
loader_version=0.17.2
minecraft_version=1.21.11
yarn_mappings=1.21.11+build.1
loader_version=0.18.2
# Mod Properties
mod_version=1.0-SNAPSHOT
maven_group=com.padbro
archives_base_name=GreeterBro
# Dependencies
# check this on https://modmuss50.me/fabric.html
fabric_version=0.134.1+1.21.10
cloth_config=20.0.148
modmenu_version=16.0.0-rc.1
fabric_version=0.139.4+1.21.11
cloth_config=21.11.152
modmenu_version=17.0.0-alpha.1
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
68 changes: 34 additions & 34 deletions src/client/java/com/padbro/greeterbro/client/GreeterBroClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,38 +15,38 @@

public class GreeterBroClient implements ClientModInitializer {

private static ConfigHolder<GreeterBroConfig> config;
private static JoinCache joinCache;
public static boolean isJoining = false;
public static final String MOD_ID = "GreeterBro";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);

public static GreeterBroConfig getConfig() {
config.save();
return config.get();
}

public static JoinCache getJoinCache() {
return joinCache;
}

public static void saveConfig() {
config.save();
}

@Override
public void onInitializeClient() {
config = AutoConfig.register(GreeterBroConfig.class, Toml4jConfigSerializer::new);
MigrationManager.migrate();

joinCache = JoinCache.loadCache();

ClientTickEvents.END_CLIENT_TICK.register(
client -> {
TickManager.onTick();
AfkManager.onTick();
});

CommandManager.register();
}
public static final String MOD_ID = "GreeterBro";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
public static boolean isJoining = false;
private static ConfigHolder<GreeterBroConfig> config;
private static JoinCache joinCache;

public static GreeterBroConfig getConfig() {
config.save();
return config.get();
}

public static JoinCache getJoinCache() {
return joinCache;
}

public static void saveConfig() {
config.save();
}

@Override
public void onInitializeClient() {
config = AutoConfig.register(GreeterBroConfig.class, Toml4jConfigSerializer::new);
MigrationManager.migrate();

joinCache = JoinCache.loadCache();

ClientTickEvents.END_CLIENT_TICK.register(
client -> {
TickManager.onTick();
AfkManager.onTick();
});

CommandManager.register();
}
}
206 changes: 104 additions & 102 deletions src/client/java/com/padbro/greeterbro/client/JoinCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.google.gson.reflect.TypeToken;
import com.padbro.greeterbro.client.config.CacheClearType;
import com.padbro.greeterbro.client.config.ReturningPlayerConfig;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
Expand All @@ -19,121 +20,122 @@
import java.util.Optional;

public class JoinCache {
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private ArrayList<PlayerCacheEntry> joins;
private String date;
private static final File file = new File("join_cache.json");

public static JoinCache loadCache() {
String currentDate = getCurrentDate();
if (!file.exists()) {
return new JoinCache(currentDate, new ArrayList<>());
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private static final File file = new File("join_cache.json");
private ArrayList<PlayerCacheEntry> joins;
private String date;

public JoinCache(String date, ArrayList<PlayerCacheEntry> joins) {
this.joins = joins;
this.date = date;
}
try (FileReader reader = new FileReader(file)) {
JoinCache joinCache = gson.fromJson(reader, new TypeToken<>() {});
ReturningPlayerConfig config = GreeterBroClient.getConfig().returningPlayerConfig;

// Don`t clear the cache if cacheClearType is Never
// Clear the cache if it`s a new day or if cacheClearType is OnNewSession
if (config.cacheClearType != CacheClearType.Never
&& (!Objects.equals(joinCache.date, currentDate)
|| config.cacheClearType == CacheClearType.OnNewSession)) {
joinCache.joins = new ArrayList<>();
joinCache.date = currentDate;
writeToFile(joinCache);
}
return joinCache;
} catch (JsonSyntaxException exception) {
return new JoinCache("", new ArrayList<>());
} catch (Exception exception) {
throw new RuntimeException(
"Cannot load player cache (%s)".formatted(file.getAbsolutePath()), exception);

public static JoinCache loadCache() {
String currentDate = getCurrentDate();
if (!file.exists()) {
return new JoinCache(currentDate, new ArrayList<>());
}
try (FileReader reader = new FileReader(file)) {
JoinCache joinCache = gson.fromJson(reader, new TypeToken<>() {
});
ReturningPlayerConfig config = GreeterBroClient.getConfig().returningPlayerConfig;

// Don`t clear the cache if cacheClearType is Never
// Clear the cache if it`s a new day or if cacheClearType is OnNewSession
if (config.cacheClearType != CacheClearType.Never
&& (!Objects.equals(joinCache.date, currentDate)
|| config.cacheClearType == CacheClearType.OnNewSession)) {
joinCache.joins = new ArrayList<>();
joinCache.date = currentDate;
writeToFile(joinCache);
}
return joinCache;
} catch (JsonSyntaxException exception) {
return new JoinCache("", new ArrayList<>());
} catch (Exception exception) {
throw new RuntimeException(
"Cannot load player cache (%s)".formatted(file.getAbsolutePath()), exception);
}
}
}

public JoinCache(String date, ArrayList<PlayerCacheEntry> joins) {
this.joins = joins;
this.date = date;
}
private static String getCurrentDate() {
return Instant.now()
.atZone(ZoneId.systemDefault())
.toLocalDate()
.format(DateTimeFormatter.ISO_LOCAL_DATE);
}

public void add(String player) {
Optional<PlayerCacheEntry> playerCacheEntry = getPlayerCacheEntry(player);
private static void writeToFile(JoinCache joinCache) {
try (FileWriter writer = new FileWriter(file)) {
gson.toJson(joinCache, writer);
} catch (IOException e) {
GreeterBroClient.LOGGER.warn("Failed to save cache data to file");
}
}

if (playerCacheEntry.isEmpty()) {
this.joins.add(new PlayerCacheEntry(player, Instant.now()));
} else {
playerCacheEntry.get().setJoinedAt(Instant.now());
public void add(String player) {
Optional<PlayerCacheEntry> playerCacheEntry = getPlayerCacheEntry(player);

if (playerCacheEntry.isEmpty()) {
this.joins.add(new PlayerCacheEntry(player, Instant.now()));
} else {
playerCacheEntry.get().setJoinedAt(Instant.now());
}
writeToFile(this);
}
writeToFile(this);
}

public boolean hasRecentlyJoined(String player) {
Optional<PlayerCacheEntry> playerCacheEntry = this.getPlayerCacheEntry(player);
if (playerCacheEntry.isEmpty()) {
return false;
public boolean hasRecentlyJoined(String player) {
Optional<PlayerCacheEntry> playerCacheEntry = this.getPlayerCacheEntry(player);
if (playerCacheEntry.isEmpty()) {
return false;
}

Instant joinedAt = playerCacheEntry.get().getJoinedAt();

return joinedAt.isAfter(
Instant.now()
.minus(
GreeterBroClient.getConfig().returningPlayerConfig.ignoreForMin,
ChronoUnit.MINUTES));
}

Instant joinedAt = playerCacheEntry.get().getJoinedAt();

return joinedAt.isAfter(
Instant.now()
.minus(
GreeterBroClient.getConfig().returningPlayerConfig.ignoreForMin,
ChronoUnit.MINUTES));
}

public boolean hasJoined(String player) {
return this.getPlayerCacheEntry(player).isPresent();
}

public void clear() {
joins = new ArrayList<>();
writeToFile(this);
}

private static String getCurrentDate() {
return Instant.now()
.atZone(ZoneId.systemDefault())
.toLocalDate()
.format(DateTimeFormatter.ISO_LOCAL_DATE);
}

private Optional<PlayerCacheEntry> getPlayerCacheEntry(String player) {
return this.joins.stream()
.filter(playerCacheEntry -> player.equals(playerCacheEntry.name))
.findFirst();
}

private static void writeToFile(JoinCache joinCache) {
try (FileWriter writer = new FileWriter(file)) {
gson.toJson(joinCache, writer);
} catch (IOException e) {
GreeterBroClient.LOGGER.warn("Failed to save cache data to file");
public boolean hasJoined(String player) {
return this.getPlayerCacheEntry(player).isPresent();
}
}

public boolean shouldClearOnJoin() {
ReturningPlayerConfig config = GreeterBroClient.getConfig().returningPlayerConfig;
return config.cacheClearType == CacheClearType.OnJoin ||
(config.cacheClearType == CacheClearType.OnNewDay &&
!Objects.equals(this.date, getCurrentDate()));
}

public static class PlayerCacheEntry {
private final String name;
private long joinedAt;

public PlayerCacheEntry(String name, Instant joinedAt) {
this.name = name;
this.joinedAt = joinedAt.toEpochMilli();

public void clear() {
joins = new ArrayList<>();
writeToFile(this);
}

private Optional<PlayerCacheEntry> getPlayerCacheEntry(String player) {
return this.joins.stream()
.filter(playerCacheEntry -> player.equals(playerCacheEntry.name))
.findFirst();
}

public Instant getJoinedAt() {
return Instant.ofEpochMilli(joinedAt);
public boolean shouldClearOnJoin() {
ReturningPlayerConfig config = GreeterBroClient.getConfig().returningPlayerConfig;
return config.cacheClearType == CacheClearType.OnJoin ||
(config.cacheClearType == CacheClearType.OnNewDay &&
!Objects.equals(this.date, getCurrentDate()));
}

public void setJoinedAt(Instant instant) {
this.joinedAt = instant.toEpochMilli();
public static class PlayerCacheEntry {
private final String name;
private long joinedAt;

public PlayerCacheEntry(String name, Instant joinedAt) {
this.name = name;
this.joinedAt = joinedAt.toEpochMilli();
}

public Instant getJoinedAt() {
return Instant.ofEpochMilli(joinedAt);
}

public void setJoinedAt(Instant instant) {
this.joinedAt = instant.toEpochMilli();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
package com.padbro.greeterbro.client.commands;

import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;

import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.padbro.greeterbro.client.managers.AfkManager;
import com.padbro.greeterbro.client.GreeterBroClient;
import com.padbro.greeterbro.client.config.AfkNotifyType;
import com.padbro.greeterbro.client.managers.AfkManager;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;

public class AfkCommand {
public static void register(LiteralArgumentBuilder<FabricClientCommandSource> root) {
root.then(literal("afk").executes(AfkCommand::afk));
}
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;

public static int afk(CommandContext<FabricClientCommandSource> context) {
FabricClientCommandSource source = context.getSource();
if (AfkManager.isAfk) {
source.sendError(Text.translatable("text.command.GreeterBro.afk.error.isAfk"));
return 0;
public class AfkCommand {
public static void register(LiteralArgumentBuilder<FabricClientCommandSource> root) {
root.then(literal("afk").executes(AfkCommand::afk));
}
AfkManager.goAfk();
if (GreeterBroClient.getConfig().afkConfig.notifyType == AfkNotifyType.Disabled) {
source.sendFeedback(
Text.translatable("text.message.GreeterBro.afk.enter_afk").formatted(Formatting.GRAY));

public static int afk(CommandContext<FabricClientCommandSource> context) {
FabricClientCommandSource source = context.getSource();
if (AfkManager.isAfk) {
source.sendError(Component.translatable("text.command.GreeterBro.afk.error.isAfk"));
return 0;
}
AfkManager.goAfk();
if (GreeterBroClient.getConfig().afkConfig.notifyType == AfkNotifyType.Disabled) {
source.sendFeedback(
Component.translatable("text.message.GreeterBro.afk.enter_afk").withStyle(ChatFormatting.GRAY));
}
return 0;
}
return 0;
}
}
Loading