Skip to content
Open
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
89 changes: 89 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Compiled class files
*.class

# Log files
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# Virtual machine crash logs
hs_err_pid*
replay_pid*

# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar

# IntelliJ IDEA
.idea/
*.iws
*.iml
*.ipr
out/
.idea_modules/

# Eclipse
.classpath
.project
.settings/
bin/

# NetBeans
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/

# VS Code
.vscode/
*.code-workspace

# macOS
.DS_Store
.AppleDouble
.LSOverride

# Windows
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/

# Linux
*~
.directory
.Trash-*

# Backup files
*.bak
*.swp
*.swo
*~

# Temporary files
*.tmp
*.temp

1 change: 1 addition & 0 deletions .idea/PlayerStats.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/copilot.data.migration.agent.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/copilot.data.migration.ask.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/copilot.data.migration.ask2agent.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/copilot.data.migration.edit.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions .idea/discord.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.artemis.the.gr8.playerstats.api.events;

import com.artemis.the.gr8.playerstats.api.StatRequest;
import com.artemis.the.gr8.playerstats.api.StatResult;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;

/**
* This event is fired whenever PlayerStats calculates a statistic result.
* This includes player stats, server stats, and top stats.
* <p>
* This event is called on the main thread after the statistic has been
* calculated but before it is sent to the requesting player.
* <p>
* You can use this event to:
* <ul>
* <li>Send stat results to external systems (like Discord via DiscordSRV)
* <li>Log stat lookups
* <li>Perform additional actions based on stat results
* </ul>
*/
public class StatCalculatedEvent extends Event {

private static final HandlerList HANDLERS = new HandlerList();

private final CommandSender sender;
private final StatRequest<?> request;
private final StatResult<?> result;

public StatCalculatedEvent(@NotNull CommandSender sender, @NotNull StatRequest<?> request, @NotNull StatResult<?> result) {
this.sender = sender;
this.request = request;
this.result = result;
}

/**
* Gets the CommandSender who requested this statistic lookup.
*
* @return the CommandSender who initiated the stat request
*/
@NotNull
public CommandSender getSender() {
return sender;
}

/**
* Gets the StatRequest that was used to calculate this statistic.
*
* @return the StatRequest containing the lookup parameters
*/
@NotNull
public StatRequest<?> getRequest() {
return request;
}

/**
* Gets the calculated StatResult containing the formatted output.
* <p>
* You can use:
* <ul>
* <li>{@link StatResult#getNumericalValue()} to get the raw number
* <li>{@link StatResult#getFormattedTextComponent()} to get the formatted Adventure TextComponent
* <li>{@link StatResult#formattedString()} to get a plain String representation
* </ul>
*
* @return the StatResult containing the calculated statistic
*/
@NotNull
public StatResult<?> getResult() {
return result;
}

@NotNull
@Override
public HandlerList getHandlers() {
return HANDLERS;
}

@NotNull
public static HandlerList getHandlerList() {
return HANDLERS;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.artemis.the.gr8.playerstats.api.events;

import net.kyori.adventure.text.TextComponent;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;

/**
* This event is fired when a player shares a statistic result to the server chat
* by clicking the share button or using the /statshare command.
* <p>
* This event is cancellable. If cancelled, the stat result will not be broadcast
* to all players.
* <p>
* You can use this event to:
* <ul>
* <li>Send shared stats to Discord via DiscordSRV
* <li>Log stat shares
* <li>Prevent certain stats from being shared
* <li>Send the stat to custom channels
* </ul>
*/
public class StatSharedEvent extends Event implements Cancellable {

private static final HandlerList HANDLERS = new HandlerList();

private final CommandSender sender;
private final TextComponent statResult;
private final int shareCode;
private boolean cancelled = false;

public StatSharedEvent(@NotNull CommandSender sender, @NotNull TextComponent statResult, int shareCode) {
this.sender = sender;
this.statResult = statResult;
this.shareCode = shareCode;
}

/**
* Gets the CommandSender who is sharing the statistic.
*
* @return the CommandSender sharing the stat
*/
@NotNull
public CommandSender getSender() {
return sender;
}

/**
* Gets the formatted statistic result that is being shared.
* This is an Adventure TextComponent with formatting, colors, and hover text.
* <p>
* For a plain String representation, you can serialize this component or
* use Adventure's PlainTextComponentSerializer.
*
* @return the formatted stat result as a TextComponent
*/
@NotNull
public TextComponent getStatResult() {
return statResult;
}

/**
* Gets the share code that was used to retrieve this statistic.
* This is the unique identifier for this particular stat share.
*
* @return the share code
*/
public int getShareCode() {
return shareCode;
}

@Override
public boolean isCancelled() {
return cancelled;
}

@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}

@NotNull
@Override
public HandlerList getHandlers() {
return HANDLERS;
}

@NotNull
public static HandlerList getHandlerList() {
return HANDLERS;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.artemis.the.gr8.playerstats.core.commands;

import com.artemis.the.gr8.playerstats.api.events.StatSharedEvent;
import com.artemis.the.gr8.playerstats.core.sharing.ShareManager;
import com.artemis.the.gr8.playerstats.core.enums.StandardMessage;
import com.artemis.the.gr8.playerstats.core.msg.OutputManager;
Expand Down Expand Up @@ -45,7 +46,15 @@ else if (shareManager.isOnCoolDown(sender.getName())) {
outputManager.sendFeedbackMsg(sender, StandardMessage.STAT_RESULTS_TOO_OLD);
} else {
commandCounter.upShareCommandCount();
outputManager.sendToAllPlayers(result.formattedValue());

// Fire the share event to expose the data, for things like DiscordSRV - DerexXD
StatSharedEvent event = new StatSharedEvent(sender, result.formattedValue(), shareCode);
org.bukkit.Bukkit.getPluginManager().callEvent(event);

// Only broadcast to all players if the event wasn't cancelled
if (!event.isCancelled()) {
outputManager.sendToAllPlayers(result.formattedValue());
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.artemis.the.gr8.playerstats.core.multithreading;

import com.artemis.the.gr8.playerstats.api.events.StatCalculatedEvent;
import com.artemis.the.gr8.playerstats.core.msg.OutputManager;
import com.artemis.the.gr8.playerstats.core.statistic.StatRequestManager;
import com.artemis.the.gr8.playerstats.api.StatRequest;
import com.artemis.the.gr8.playerstats.api.StatResult;
import com.artemis.the.gr8.playerstats.core.utils.MyLogger;
import com.artemis.the.gr8.playerstats.core.enums.StandardMessage;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -56,9 +58,13 @@ public void run() throws IllegalStateException {

try {
StatResult<?> result = StatRequestManager.execute(statRequest);

// Fire the event to expose the data, for things like DiscordSRV - DerexXD
StatCalculatedEvent event = new StatCalculatedEvent(statRequester, statRequest, result);
Bukkit.getPluginManager().callEvent(event);

outputManager.sendToCommandSender(statRequester, result.formattedComponent());
}
catch (ConcurrentModificationException e) {
} catch (ConcurrentModificationException e) {
if (!statRequest.getSettings().isConsoleSender()) {
outputManager.sendFeedbackMsg(statRequester, StandardMessage.UNKNOWN_ERROR);
}
Expand Down