Skip to content
Closed
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
68 changes: 68 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
tab_width = 2

[.gitignore]
max_line_length = unset

[*.md]
max_line_length = unset

[*.feature]
tab_width = 4

[*.gsp]
indent_size = 4
tab_width = 4

[*.haml]
tab_width = 4

[*.less]
tab_width = 4

[*.styl]
tab_width = 4

[.editorconfig]
max_line_length = unset

[{*.as,*.js2,*.es}]
indent_size = 4
tab_width = 4

[{*.cfml,*.cfm,*.cfc}]
indent_size = 4
tab_width = 4

[{*.cjs,*.js}]
max_line_length = 80

[{*.gradle,*.groovy,*.gant,*.gdsl,*.gy,*.gson}]
indent_size = 4
tab_width = 4

[{*.jspx,*.tagx}]
indent_size = 4
tab_width = 4

[{*.kts,*.kt}]
indent_size = 4
tab_width = 4

[{*.vsl,*.vm,*.ft}]
indent_size = 4
tab_width = 4

[{*.xjsp,*.tag,*.jsf,*.jsp,*.jspf,*.tagf}]
indent_size = 4
tab_width = 4

[{*.yml,*.yaml}]
tab_width = 4

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
build/
out/
classes/
.factorypath

# eclipse

Expand Down
51 changes: 47 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'fabric-loom' version '1.10.1'
id 'fabric-loom' version '1.10-SNAPSHOT'
id 'maven-publish'
id 'com.github.johnrengelman.shadow' version "8+"
}

group = project.maven_group
Expand All @@ -9,7 +10,24 @@ base {
archivesName = project.archives_base_name
}

configurations {
embed
compileOnly.extendsFrom(embed)
}

shadowJar {
configurations = [project.configurations.embed]
exclude('META-INF/services/**')
relocate "com.moandjiezana", "dcshadow.com.moandjiezana"
}

repositories {
mavenCentral()
maven {
url = uri("https://repo.opencollab.dev/main/")
}
maven { url 'https://jitpack.io' }

// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
Expand All @@ -21,7 +39,7 @@ loom {
splitEnvironmentSourceSets()

mods {
"modid" {
"altx" {
sourceSet sourceSets.main
sourceSet sourceSets.client
}
Expand All @@ -35,12 +53,23 @@ dependencies {
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"

// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"

include(modImplementation('me.lucko:fabric-permissions-api:0.3.3'))

// config
embed implementation("de.erdbeerbaerlp:toml4j:dd60f51")

// floodgate integration
compileOnly('org.geysermc.floodgate:api:2.2.4-SNAPSHOT')

// justsync integration
compileOnly('com.github.OrdinarySMP:DiscordJustSync:master-SNAPSHOT')

}

tasks.build.dependsOn(tasks.shadowJar)

processResources {
inputs.property "version", project.version

Expand All @@ -63,12 +92,26 @@ java {
targetCompatibility = JavaVersion.VERSION_21
}

remapJar {
// wait until the shadowJar is done
dependsOn(shadowJar)
mustRunAfter(shadowJar)
// Set the input jar for the task. Here use the shadow Jar that include the .class of the transitive dependency
inputFile = file(shadowJar.archiveFile)
}


jar {
from("LICENSE") {
rename { "${it}_${project.base.archivesName.get()}"}
}
}

artifacts {
archives tasks.shadowJar
}


// configure the maven publication
publishing {
publications {
Expand Down
Empty file modified gradlew
100644 → 100755
Empty file.
15 changes: 6 additions & 9 deletions src/main/java/com/xadale/playerlogger/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@

public class Commands {

private final PlayerLogger altx;

public Commands(PlayerLogger altx) {
this.altx = altx;
}

public void register() {
// Register the command
CommandRegistrationCallback.EVENT.register(
Expand All @@ -42,7 +36,9 @@ public void register() {

if (Permissions.check(source, "altx.trace", 4)) {
help.append(
"\n§b/altx trace <player> §fShows all players on given players IP address");
"\n"
+ "§b/altx trace <player> §fShows all players on given players IP"
+ " address");

if (Permissions.check(source, "altx.viewips", 4)) {
help.append(
Expand Down Expand Up @@ -85,7 +81,8 @@ public void register() {
.executes(
(context) ->
HandleAltsCommand.execute(
context, this.altx.getLogFile()))))
context,
PlayerLogger.getInstance().getIpAssRepository()))))

// Command list
.then(
Expand All @@ -94,7 +91,7 @@ public void register() {
.executes(
(context) ->
ListIpsWithMultiplePlayers.execute(
context, this.altx.getLogFile()))));
context, PlayerLogger.getInstance().getIpAssRepository()))));
});
}
}
20 changes: 20 additions & 0 deletions src/main/java/com/xadale/playerlogger/IpLogger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.xadale.playerlogger;

import com.xadale.playerlogger.data.IpAss;
import com.xadale.playerlogger.repositories.IpAssRepository;
import java.util.Optional;
import java.util.UUID;

public class IpLogger {

public static void handleJoin(String ip, UUID uuid) {
IpAssRepository ipAssdataRepository = PlayerLogger.getInstance().getIpAssRepository();
Optional<IpAss> ipAss = ipAssdataRepository.get(ip);
if (ipAss.isEmpty()) {
ipAssdataRepository.add(new IpAss(ip, uuid));
return;
}
ipAss.get().addUUid(uuid);
NotificationHandler.handleNotif(ipAss.get(), uuid);
}
}
158 changes: 158 additions & 0 deletions src/main/java/com/xadale/playerlogger/NotificationHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package com.xadale.playerlogger;

import com.xadale.playerlogger.compat.JustSyncIntegration;
import com.xadale.playerlogger.data.IpAss;
import com.xadale.playerlogger.data.LastReadNotif;
import com.xadale.playerlogger.data.Notif;
import com.xadale.playerlogger.repositories.NotifRepository;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;

public class NotificationHandler {

public static void handleNotif(IpAss ipAss, UUID uuid) {
if (!PlayerLogger.getInstance().getConfig().altNotifs.enableNotifs) {
return;
}
List<UUID> uuids = ipAss.getUuids();
List<UUID> linkedUuids = JustSyncIntegration.getIntegration().getRelatedUuids(uuid);
// TODO: filter authorized accounts
List<UUID> filteredUuids = uuids.stream().filter(u -> !linkedUuids.contains(u)).toList();
if (filteredUuids.isEmpty()) {
return;
}
String message = getMessage(uuid, filteredUuids);

PlayerLogger.getInstance()
.getServer()
.getPlayerManager()
.getPlayerList()
.forEach(
player -> {
if (Permissions.check(player, "altx.notify", 4)) {
player.sendMessage(Text.literal(message).formatted(Formatting.RED), false);
PlayerLogger.getInstance()
.getLastReadNotifRepository()
.get(player.getUuid())
.get()
.setLastNotifId(getLastNotifId() + 1);
;
}
});
// File log =
// PlayerLogger.getConfigFolder().resolve(PlayerLogger.modId +
// ".notifications.log").toFile();
String my_file_name =
PlayerLogger.getConfigFolder()
.resolve(PlayerLogger.modId + ".notifications.log")
.toString();
try (BufferedWriter output = new BufferedWriter(new FileWriter(my_file_name, true))) {
output.append(LocalDateTime.now().toString() + ' ');
output.append(message);
output.newLine();
} catch (IOException ignored) {
}

Notif notif = new Notif(getLastNotifId() + 1, uuid, filteredUuids, LocalDateTime.now());
PlayerLogger.getInstance().getNotifRepository().add(notif);
}

public static void onJoin(
ServerPlayNetworkHandler handler, PacketSender sender, MinecraftServer server) {
ServerPlayerEntity player = handler.getPlayer();

// has permission for notifications
if (!Permissions.check(player, "altx.notify", 4)) {
return;
}

// if not already seen notifications before (joined with permission before)
// create last read tracking object
Optional<LastReadNotif> lastReadNotif =
PlayerLogger.getInstance().getLastReadNotifRepository().get(player.getUuid());
if (lastReadNotif.isEmpty()) {
LastReadNotif newLastReadNotif = new LastReadNotif(player.getUuid(), getLastNotifId());
PlayerLogger.getInstance().getLastReadNotifRepository().add(newLastReadNotif);
return;
}

if (!PlayerLogger.getInstance().getConfig().altNotifs.showMissedNotifsOnJoin) {
return;
}

// show missed notifications
List<Notif> missedNotifs =
getMissedNotifs(
lastReadNotif.get().getLastNotifId(),
PlayerLogger.getInstance().getConfig().altNotifs.notificationPeriod);
for (Notif notif : missedNotifs) {
player.sendMessage(
Text.literal(getMessage(notif.getUuid(), notif.getAlts())).formatted(Formatting.RED),
false);
}

lastReadNotif.get().setLastNotifId(getLastNotifId());
}

public static List<Notif> getMissedNotifs(long afterId, int hours) {
LocalDateTime cutoff = LocalDateTime.now().minusHours(hours);
NotifRepository repository = PlayerLogger.getInstance().getNotifRepository();

return repository
.getAll()
.filter(notif -> notif.getId() > afterId)
.filter(notif -> notif.getTime() != null && !notif.getTime().isBefore(cutoff))
.toList();
}

public static String getMessage(UUID uuid, List<UUID> uuids) {
return "Player "
+ Utils.getPlayerName(uuid)
+ " is a potential alt of: "
+ uuids.stream().map(Utils::getPlayerName).toList()
+ ".";
}

public static int getLastNotifId() {
return PlayerLogger.getInstance()
.getNotifRepository()
.getAll()
.mapToInt(Notif::getId)
.max()
.orElse(0);
}

public static void purgeOldNotifs(int hours) {
LocalDateTime cutoff = LocalDateTime.now().minusHours(hours);
NotifRepository repository = PlayerLogger.getInstance().getNotifRepository();

Optional<Notif> newestNotifOptional = repository.get(getLastNotifId());

if (newestNotifOptional.isEmpty()) {
return;
}

Notif newestNotif = newestNotifOptional.get();

List<Notif> toRemove =
repository
.getAll()
.filter(notif -> notif != newestNotif)
.filter(notif -> notif.getTime() != null && notif.getTime().isBefore(cutoff))
.toList();

toRemove.forEach(repository::remove);
}
}
Loading