New
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.dirtbagmc</groupId>
|
||||
<artifactId>DirtReferrals</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>DirtReferrals</name>
|
||||
<description>Referral tracking plugin for Paper</description>
|
||||
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>papermc-repo</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.21.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.46.1.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<configuration>
|
||||
<release>21</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,152 @@
|
||||
package com.dirtbagmc.dirtreferrals;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AdminCommand implements CommandExecutor {
|
||||
|
||||
private final DirtReferralsPlugin plugin;
|
||||
|
||||
public AdminCommand(DirtReferralsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!sender.hasPermission("dirtreferrals.admin")) {
|
||||
plugin.getMessageManager().send(sender, "no-permission");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
plugin.getMessageManager().send(sender, "usage-admin");
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "reload" -> {
|
||||
plugin.reloadPlugin();
|
||||
plugin.getMessageManager().send(sender, "reloaded");
|
||||
return true;
|
||||
}
|
||||
case "stats" -> {
|
||||
if (args.length < 2) {
|
||||
plugin.getMessageManager().send(sender, "usage-stats");
|
||||
return true;
|
||||
}
|
||||
|
||||
UUID uuid = plugin.getDatabaseManager().getPlayerUuidByName(args[1]);
|
||||
if (uuid == null) {
|
||||
plugin.getMessageManager().send(sender, "no-data");
|
||||
return true;
|
||||
}
|
||||
|
||||
String name = plugin.getDatabaseManager().getPlayerName(uuid);
|
||||
int count = plugin.getDatabaseManager().getReferralCount(uuid);
|
||||
|
||||
sender.sendMessage(plugin.getMessageManager().get("stats-header")
|
||||
.replace("%player%", name == null ? args[1] : name));
|
||||
sender.sendMessage(plugin.getMessageManager().get("stats-count")
|
||||
.replace("%count%", String.valueOf(count)));
|
||||
return true;
|
||||
}
|
||||
case "top" -> {
|
||||
List<TopEntry> top = plugin.getDatabaseManager().getTopReferrers(10);
|
||||
sender.sendMessage(plugin.getMessageManager().get("top-header"));
|
||||
|
||||
if (top.isEmpty()) {
|
||||
plugin.getMessageManager().send(sender, "no-data");
|
||||
return true;
|
||||
}
|
||||
|
||||
int position = 1;
|
||||
for (TopEntry entry : top) {
|
||||
sender.sendMessage(plugin.getMessageManager().get("top-entry")
|
||||
.replace("%position%", String.valueOf(position))
|
||||
.replace("%player%", entry.getName())
|
||||
.replace("%count%", String.valueOf(entry.getCount())));
|
||||
position++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "give" -> {
|
||||
if (args.length < 3) {
|
||||
plugin.getMessageManager().send(sender, "usage-give");
|
||||
return true;
|
||||
}
|
||||
|
||||
UUID uuid = plugin.getDatabaseManager().getPlayerUuidByName(args[1]);
|
||||
if (uuid == null) {
|
||||
plugin.getMessageManager().send(sender, "no-data");
|
||||
return true;
|
||||
}
|
||||
|
||||
int amount;
|
||||
try {
|
||||
amount = Integer.parseInt(args[2]);
|
||||
} catch (NumberFormatException e) {
|
||||
plugin.getMessageManager().send(sender, "invalid-number");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (amount < 0) {
|
||||
plugin.getMessageManager().send(sender, "invalid-number");
|
||||
return true;
|
||||
}
|
||||
|
||||
plugin.getDatabaseManager().addReferralCount(uuid, amount);
|
||||
|
||||
sender.sendMessage(plugin.getMessageManager().get("credit-added")
|
||||
.replace("%amount%", String.valueOf(amount))
|
||||
.replace("%player%", plugin.getDatabaseManager().getPlayerName(uuid)));
|
||||
return true;
|
||||
}
|
||||
case "take" -> {
|
||||
if (args.length < 3) {
|
||||
plugin.getMessageManager().send(sender, "usage-take");
|
||||
return true;
|
||||
}
|
||||
|
||||
UUID uuid = plugin.getDatabaseManager().getPlayerUuidByName(args[1]);
|
||||
if (uuid == null) {
|
||||
plugin.getMessageManager().send(sender, "no-data");
|
||||
return true;
|
||||
}
|
||||
|
||||
int amount;
|
||||
try {
|
||||
amount = Integer.parseInt(args[2]);
|
||||
} catch (NumberFormatException e) {
|
||||
plugin.getMessageManager().send(sender, "invalid-number");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (amount < 0) {
|
||||
plugin.getMessageManager().send(sender, "invalid-number");
|
||||
return true;
|
||||
}
|
||||
|
||||
int current = plugin.getDatabaseManager().getReferralCount(uuid);
|
||||
if (current < amount) {
|
||||
plugin.getMessageManager().send(sender, "not-enough-credit");
|
||||
return true;
|
||||
}
|
||||
|
||||
plugin.getDatabaseManager().setReferralCount(uuid, current - amount);
|
||||
|
||||
sender.sendMessage(plugin.getMessageManager().get("credit-removed")
|
||||
.replace("%amount%", String.valueOf(amount))
|
||||
.replace("%player%", plugin.getDatabaseManager().getPlayerName(uuid)));
|
||||
return true;
|
||||
}
|
||||
default -> {
|
||||
plugin.getMessageManager().send(sender, "unknown-subcommand");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
package com.dirtbagmc.dirtreferrals;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DatabaseManager {
|
||||
|
||||
private final DirtReferralsPlugin plugin;
|
||||
private Connection connection;
|
||||
|
||||
public DatabaseManager(DirtReferralsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
try {
|
||||
if (!plugin.getDataFolder().exists()) {
|
||||
plugin.getDataFolder().mkdirs();
|
||||
}
|
||||
|
||||
String fileName = plugin.getConfig().getString("database.file", "referrals.db");
|
||||
File dbFile = new File(plugin.getDataFolder(), fileName);
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile.getAbsolutePath());
|
||||
|
||||
createTables();
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed to initialize SQLite database.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void createTables() throws SQLException {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS players (
|
||||
uuid TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
referral_count INTEGER NOT NULL DEFAULT 0
|
||||
)
|
||||
""");
|
||||
|
||||
statement.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS referrals (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
referrer_uuid TEXT NOT NULL,
|
||||
referred_uuid TEXT NOT NULL,
|
||||
referred_name TEXT NOT NULL,
|
||||
join_host TEXT,
|
||||
ip_address TEXT,
|
||||
counted INTEGER NOT NULL DEFAULT 0,
|
||||
created_at INTEGER NOT NULL
|
||||
)
|
||||
""");
|
||||
|
||||
statement.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS player_ips (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
player_uuid TEXT NOT NULL,
|
||||
ip_address TEXT NOT NULL,
|
||||
created_at INTEGER NOT NULL
|
||||
)
|
||||
""");
|
||||
|
||||
statement.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS claimed_rewards (
|
||||
referrer_uuid TEXT NOT NULL,
|
||||
milestone INTEGER NOT NULL,
|
||||
claimed_at INTEGER NOT NULL,
|
||||
PRIMARY KEY (referrer_uuid, milestone)
|
||||
)
|
||||
""");
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed to close database connection.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void upsertPlayer(UUID uuid, String name) {
|
||||
String sql = """
|
||||
INSERT INTO players (uuid, name, referral_count)
|
||||
VALUES (?, ?, 0)
|
||||
ON CONFLICT(uuid) DO UPDATE SET name = excluded.name
|
||||
""";
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, uuid.toString());
|
||||
ps.setString(2, name);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed to upsert player " + name);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String getPlayerName(UUID uuid) {
|
||||
String sql = "SELECT name FROM players WHERE uuid = ?";
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, uuid.toString());
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return rs.getString("name");
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed to get player name.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public UUID getPlayerUuidByName(String name) {
|
||||
String sql = "SELECT uuid FROM players WHERE LOWER(name) = LOWER(?)";
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, name);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return UUID.fromString(rs.getString("uuid"));
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed to get UUID by player name.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getReferralCount(UUID uuid) {
|
||||
String sql = "SELECT referral_count FROM players WHERE uuid = ?";
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, uuid.toString());
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return rs.getInt("referral_count");
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed to get referral count.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setReferralCount(UUID uuid, int count) {
|
||||
String sql = "UPDATE players SET referral_count = ? WHERE uuid = ?";
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setInt(1, count);
|
||||
ps.setString(2, uuid.toString());
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed to set referral count.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void addReferralCount(UUID uuid, int amount) {
|
||||
setReferralCount(uuid, Math.max(0, getReferralCount(uuid) + amount));
|
||||
}
|
||||
|
||||
public boolean hasReferralRecord(UUID referrerUuid, UUID referredUuid) {
|
||||
String sql = "SELECT 1 FROM referrals WHERE referrer_uuid = ? AND referred_uuid = ? LIMIT 1";
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, referrerUuid.toString());
|
||||
ps.setString(2, referredUuid.toString());
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
return rs.next();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed checking referral record.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasAnyReferralRecordForReferred(UUID referredUuid) {
|
||||
String sql = "SELECT 1 FROM referrals WHERE referred_uuid = ? LIMIT 1";
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, referredUuid.toString());
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
return rs.next();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed checking referred player history.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void insertReferral(UUID referrerUuid, UUID referredUuid, String referredName, String joinHost, String ipAddress, boolean counted) {
|
||||
String sql = """
|
||||
INSERT INTO referrals (referrer_uuid, referred_uuid, referred_name, join_host, ip_address, counted, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
""";
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, referrerUuid.toString());
|
||||
ps.setString(2, referredUuid.toString());
|
||||
ps.setString(3, referredName);
|
||||
ps.setString(4, joinHost);
|
||||
ps.setString(5, ipAddress);
|
||||
ps.setInt(6, counted ? 1 : 0);
|
||||
ps.setLong(7, System.currentTimeMillis());
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed to insert referral.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlayerIp(UUID playerUuid, String ipAddress) {
|
||||
String checkSql = "SELECT 1 FROM player_ips WHERE player_uuid = ? AND ip_address = ? LIMIT 1";
|
||||
String insertSql = "INSERT INTO player_ips (player_uuid, ip_address, created_at) VALUES (?, ?, ?)";
|
||||
|
||||
try (PreparedStatement check = connection.prepareStatement(checkSql)) {
|
||||
check.setString(1, playerUuid.toString());
|
||||
check.setString(2, ipAddress);
|
||||
try (ResultSet rs = check.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed checking existing player IP.");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
try (PreparedStatement insert = connection.prepareStatement(insertSql)) {
|
||||
insert.setString(1, playerUuid.toString());
|
||||
insert.setString(2, ipAddress);
|
||||
insert.setLong(3, System.currentTimeMillis());
|
||||
insert.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed storing player IP.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean playerHasIp(UUID playerUuid, String ipAddress) {
|
||||
String sql = "SELECT 1 FROM player_ips WHERE player_uuid = ? AND ip_address = ? LIMIT 1";
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, playerUuid.toString());
|
||||
ps.setString(2, ipAddress);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
return rs.next();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed checking player IP.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean anyReferralUsesIpForReferrer(UUID referrerUuid, String ipAddress) {
|
||||
String sql = "SELECT 1 FROM referrals WHERE referrer_uuid = ? AND ip_address = ? LIMIT 1";
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, referrerUuid.toString());
|
||||
ps.setString(2, ipAddress);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
return rs.next();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed checking referral IP reuse.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasClaimedReward(UUID referrerUuid, int milestone) {
|
||||
String sql = "SELECT 1 FROM claimed_rewards WHERE referrer_uuid = ? AND milestone = ? LIMIT 1";
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, referrerUuid.toString());
|
||||
ps.setInt(2, milestone);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
return rs.next();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed checking claimed reward.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setRewardClaimed(UUID referrerUuid, int milestone) {
|
||||
String sql = """
|
||||
INSERT OR IGNORE INTO claimed_rewards (referrer_uuid, milestone, claimed_at)
|
||||
VALUES (?, ?, ?)
|
||||
""";
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, referrerUuid.toString());
|
||||
ps.setInt(2, milestone);
|
||||
ps.setLong(3, System.currentTimeMillis());
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed marking reward as claimed.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public List<TopEntry> getTopReferrers(int limit) {
|
||||
List<TopEntry> results = new ArrayList<>();
|
||||
String sql = "SELECT uuid, name, referral_count FROM players ORDER BY referral_count DESC, name ASC LIMIT ?";
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setInt(1, limit);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
results.add(new TopEntry(
|
||||
UUID.fromString(rs.getString("uuid")),
|
||||
rs.getString("name"),
|
||||
rs.getInt("referral_count")
|
||||
));
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().severe("Failed loading top referrers.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.dirtbagmc.dirtreferrals;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class DirtReferralsPlugin extends JavaPlugin {
|
||||
|
||||
private File messagesFile;
|
||||
private FileConfiguration messages;
|
||||
|
||||
private DatabaseManager databaseManager;
|
||||
private ReferralManager referralManager;
|
||||
private MessageManager messageManager;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
saveDefaultConfig();
|
||||
createMessagesFile();
|
||||
this.messageManager = new MessageManager(this);
|
||||
this.databaseManager = new DatabaseManager(this);
|
||||
this.databaseManager.initialize();
|
||||
this.referralManager = new ReferralManager(this);
|
||||
|
||||
getCommand("refer").setExecutor(new ReferralCommand(this));
|
||||
getCommand("dirtreferrals").setExecutor(new AdminCommand(this));
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new PlayerListener(this), this);
|
||||
|
||||
getLogger().info("DirtReferrals enabled.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (referralManager != null) {
|
||||
referralManager.shutdown();
|
||||
}
|
||||
if (databaseManager != null) {
|
||||
databaseManager.close();
|
||||
}
|
||||
getLogger().info("DirtReferrals disabled.");
|
||||
}
|
||||
|
||||
public void reloadPlugin() {
|
||||
reloadConfig();
|
||||
reloadMessages();
|
||||
if (referralManager != null) {
|
||||
referralManager.reload();
|
||||
}
|
||||
}
|
||||
|
||||
private void createMessagesFile() {
|
||||
if (!getDataFolder().exists()) {
|
||||
getDataFolder().mkdirs();
|
||||
}
|
||||
|
||||
messagesFile = new File(getDataFolder(), "messages.yml");
|
||||
if (!messagesFile.exists()) {
|
||||
saveResource("messages.yml", false);
|
||||
}
|
||||
messages = YamlConfiguration.loadConfiguration(messagesFile);
|
||||
}
|
||||
|
||||
public void reloadMessages() {
|
||||
messages = YamlConfiguration.loadConfiguration(messagesFile);
|
||||
}
|
||||
|
||||
public FileConfiguration getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public void saveMessages() {
|
||||
try {
|
||||
messages.save(messagesFile);
|
||||
} catch (IOException e) {
|
||||
getLogger().severe("Could not save messages.yml");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public DatabaseManager getDatabaseManager() {
|
||||
return databaseManager;
|
||||
}
|
||||
|
||||
public ReferralManager getReferralManager() {
|
||||
return referralManager;
|
||||
}
|
||||
|
||||
public MessageManager getMessageManager() {
|
||||
return messageManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.dirtbagmc.dirtreferrals;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class MessageManager {
|
||||
|
||||
private final DirtReferralsPlugin plugin;
|
||||
|
||||
public MessageManager(DirtReferralsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public String get(String path) {
|
||||
String prefix = plugin.getMessages().getString("prefix", "&6[DirtReferrals] ");
|
||||
String message = plugin.getMessages().getString(path, "&cMissing message: " + path);
|
||||
return color(prefix + message);
|
||||
}
|
||||
|
||||
public String getRaw(String path) {
|
||||
return color(plugin.getMessages().getString(path, "&cMissing message: " + path));
|
||||
}
|
||||
|
||||
public String color(String input) {
|
||||
return ChatColor.translateAlternateColorCodes('&', input);
|
||||
}
|
||||
|
||||
public void send(CommandSender sender, String path) {
|
||||
sender.sendMessage(get(path));
|
||||
}
|
||||
|
||||
public void sendRaw(CommandSender sender, String message) {
|
||||
sender.sendMessage(color(message));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.dirtbagmc.dirtreferrals;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
|
||||
public class PlayerListener implements Listener {
|
||||
|
||||
private final DirtReferralsPlugin plugin;
|
||||
|
||||
public PlayerListener(DirtReferralsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onLogin(PlayerLoginEvent event) {
|
||||
String joinHost = null;
|
||||
|
||||
try {
|
||||
if (event.getHostname() != null && !event.getHostname().isBlank()) {
|
||||
joinHost = event.getHostname();
|
||||
}
|
||||
} catch (NoSuchMethodError ignored) {
|
||||
}
|
||||
|
||||
if (joinHost != null) {
|
||||
plugin.getLogger().info("Player " + event.getPlayer().getName() + " joined with hostname: " + joinHost);
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
plugin.getReferralManager().queueReferral(player, joinHost);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
plugin.getReferralManager().registerPlayer(player);
|
||||
plugin.getReferralManager().processQueuedReferral(player);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.dirtbagmc.dirtreferrals;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ReferralCommand implements CommandExecutor {
|
||||
|
||||
private final DirtReferralsPlugin plugin;
|
||||
|
||||
public ReferralCommand(DirtReferralsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
plugin.getMessageManager().send(sender, "player-only");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!player.hasPermission("dirtreferrals.use")) {
|
||||
plugin.getMessageManager().send(player, "no-permission");
|
||||
return true;
|
||||
}
|
||||
|
||||
String address = plugin.getReferralManager().getReferralAddress(player);
|
||||
String message = plugin.getMessageManager().get("referral-link")
|
||||
.replace("%referral_ip%", address);
|
||||
|
||||
player.sendMessage(message);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
package com.dirtbagmc.dirtreferrals;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ReferralManager {
|
||||
|
||||
private final DirtReferralsPlugin plugin;
|
||||
private final Map<UUID, PendingReferral> pendingReferrals = new ConcurrentHashMap<>();
|
||||
|
||||
public ReferralManager(DirtReferralsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
pendingReferrals.clear();
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
pendingReferrals.clear();
|
||||
}
|
||||
|
||||
public String getReferralAddress(Player player) {
|
||||
String baseDomain = plugin.getConfig().getString("domain.base", "dirtbagmc.com");
|
||||
boolean lowercase = plugin.getConfig().getBoolean("domain.use-lowercase-playernames", true);
|
||||
String name = lowercase ? player.getName().toLowerCase(Locale.ROOT) : player.getName();
|
||||
return name + "." + baseDomain;
|
||||
}
|
||||
|
||||
public void registerPlayer(Player player) {
|
||||
plugin.getDatabaseManager().upsertPlayer(player.getUniqueId(), player.getName());
|
||||
|
||||
String ip = getPlayerIp(player);
|
||||
if (ip != null && plugin.getConfig().getBoolean("referral.store-ip-addresses", true)) {
|
||||
plugin.getDatabaseManager().addPlayerIp(player.getUniqueId(), transformIp(ip));
|
||||
}
|
||||
}
|
||||
|
||||
public void queueReferral(Player player, String joinHost) {
|
||||
if (joinHost == null || joinHost.isBlank()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String baseDomain = plugin.getConfig().getString("domain.base", "dirtbagmc.com").toLowerCase(Locale.ROOT);
|
||||
String normalizedHost = joinHost.toLowerCase(Locale.ROOT);
|
||||
|
||||
if (!normalizedHost.endsWith("." + baseDomain)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String subdomain = normalizedHost.substring(0, normalizedHost.length() - ("." + baseDomain).length());
|
||||
if (subdomain.isBlank()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UUID referrerUuid = plugin.getDatabaseManager().getPlayerUuidByName(subdomain);
|
||||
if (referrerUuid == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
pendingReferrals.put(player.getUniqueId(), new PendingReferral(referrerUuid, normalizedHost, System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
public void processQueuedReferral(Player player) {
|
||||
PendingReferral pending = pendingReferrals.remove(player.getUniqueId());
|
||||
if (pending == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
UUID referredUuid = player.getUniqueId();
|
||||
UUID referrerUuid = pending.referrerUuid();
|
||||
|
||||
if (plugin.getConfig().getBoolean("referral.block-self-referrals", true) && referredUuid.equals(referrerUuid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getConfig().getBoolean("referral.count-only-first-join", true)
|
||||
&& plugin.getDatabaseManager().hasAnyReferralRecordForReferred(referredUuid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getDatabaseManager().hasReferralRecord(referrerUuid, referredUuid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String rawIp = getPlayerIp(player);
|
||||
String transformedIp = rawIp == null ? null : transformIp(rawIp);
|
||||
|
||||
if (plugin.getConfig().getBoolean("referral.block-same-ip", true) && transformedIp != null) {
|
||||
if (plugin.getConfig().getBoolean("referral.compare-against-referrer-known-ips", true)
|
||||
&& plugin.getDatabaseManager().playerHasIp(referrerUuid, transformedIp)) {
|
||||
alertBlocked(player.getName(), plugin.getDatabaseManager().getPlayerName(referrerUuid), "same IP as referrer");
|
||||
plugin.getDatabaseManager().insertReferral(referrerUuid, referredUuid, player.getName(), pending.joinHost(), transformedIp, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getConfig().getBoolean("referral.compare-against-other-referred-ips", true)
|
||||
&& plugin.getDatabaseManager().anyReferralUsesIpForReferrer(referrerUuid, transformedIp)) {
|
||||
alertBlocked(player.getName(), plugin.getDatabaseManager().getPlayerName(referrerUuid), "reused referral IP");
|
||||
plugin.getDatabaseManager().insertReferral(referrerUuid, referredUuid, player.getName(), pending.joinHost(), transformedIp, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int requiredMinutes = plugin.getConfig().getInt("referral.require-player-to-stay-online-minutes", 5);
|
||||
if (requiredMinutes <= 0) {
|
||||
countReferralNow(player, referrerUuid, pending.joinHost(), transformedIp);
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
Player online = Bukkit.getPlayer(referredUuid);
|
||||
if (online == null || !online.isOnline()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getDatabaseManager().hasReferralRecord(referrerUuid, referredUuid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
countReferralNow(online, referrerUuid, pending.joinHost(), transformedIp);
|
||||
}, requiredMinutes * 60L * 20L);
|
||||
}
|
||||
|
||||
private void countReferralNow(Player referredPlayer, UUID referrerUuid, String joinHost, String transformedIp) {
|
||||
UUID referredUuid = referredPlayer.getUniqueId();
|
||||
|
||||
if (plugin.getDatabaseManager().hasReferralRecord(referrerUuid, referredUuid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.getDatabaseManager().insertReferral(referrerUuid, referredUuid, referredPlayer.getName(), joinHost, transformedIp, true);
|
||||
plugin.getDatabaseManager().addReferralCount(referrerUuid, 1);
|
||||
|
||||
String referrerName = plugin.getDatabaseManager().getPlayerName(referrerUuid);
|
||||
checkMilestones(referrerUuid, referrerName);
|
||||
|
||||
String message = plugin.getMessageManager().get("referral-counted")
|
||||
.replace("%referrer%", referrerName == null ? "Unknown" : referrerName);
|
||||
referredPlayer.sendMessage(message);
|
||||
}
|
||||
|
||||
private void checkMilestones(UUID referrerUuid, String referrerName) {
|
||||
int count = plugin.getDatabaseManager().getReferralCount(referrerUuid);
|
||||
ConfigurationSection milestones = plugin.getConfig().getConfigurationSection("rewards.milestones");
|
||||
if (milestones == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String key : milestones.getKeys(false)) {
|
||||
int milestone;
|
||||
try {
|
||||
milestone = Integer.parseInt(key);
|
||||
} catch (NumberFormatException e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count < milestone) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (plugin.getDatabaseManager().hasClaimedReward(referrerUuid, milestone)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> commands = plugin.getConfig().getStringList("rewards.milestones." + key + ".commands");
|
||||
for (String command : commands) {
|
||||
String parsed = command
|
||||
.replace("%referrer%", referrerName == null ? "Unknown" : referrerName)
|
||||
.replace("%count%", String.valueOf(count))
|
||||
.replace("%milestone%", String.valueOf(milestone));
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), parsed);
|
||||
}
|
||||
|
||||
plugin.getDatabaseManager().setRewardClaimed(referrerUuid, milestone);
|
||||
|
||||
Player referrer = Bukkit.getPlayer(referrerUuid);
|
||||
if (referrer != null && referrer.isOnline()) {
|
||||
String rewardMessage = plugin.getConfig().getString("rewards.milestones." + key + ".message",
|
||||
"&aYou reached " + milestone + " referrals and earned a reward!");
|
||||
referrer.sendMessage(plugin.getMessageManager().color(
|
||||
plugin.getMessages().getString("prefix", "&6[DirtReferrals] ") + rewardMessage
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void alertBlocked(String referredName, String referrerName, String reason) {
|
||||
if (!plugin.getConfig().getBoolean("alerts.notify-on-blocked-same-ip", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String permission = plugin.getConfig().getString("alerts.notify-permission", "dirtreferrals.alerts");
|
||||
String message = plugin.getMessages().getString("prefix", "&6[DirtReferrals] ")
|
||||
+ "&cBlocked referral: &e" + referredName + " &7-> &e"
|
||||
+ (referrerName == null ? "Unknown" : referrerName) + " &7(" + reason + ")";
|
||||
|
||||
String colored = plugin.getMessageManager().color(message);
|
||||
for (Player online : Bukkit.getOnlinePlayers()) {
|
||||
if (online.hasPermission(permission)) {
|
||||
online.sendMessage(colored);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getPlayerIp(Player player) {
|
||||
if (player.getAddress() == null) {
|
||||
return null;
|
||||
}
|
||||
InetAddress address = player.getAddress().getAddress();
|
||||
return address == null ? null : address.getHostAddress();
|
||||
}
|
||||
|
||||
private String transformIp(String ip) {
|
||||
boolean hash = plugin.getConfig().getBoolean("referral.hash-ip-addresses", false);
|
||||
if (!hash) {
|
||||
return ip;
|
||||
}
|
||||
return Integer.toHexString(ip.hashCode());
|
||||
}
|
||||
|
||||
private record PendingReferral(UUID referrerUuid, String joinHost, long createdAt) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.dirtbagmc.dirtreferrals;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class TopEntry {
|
||||
|
||||
private final UUID uuid;
|
||||
private final String name;
|
||||
private final int count;
|
||||
|
||||
public TopEntry(UUID uuid, String name, int count) {
|
||||
this.uuid = uuid;
|
||||
this.name = name;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
domain:
|
||||
base: "dirtbagmc.com"
|
||||
use-lowercase-playernames: true
|
||||
|
||||
referral:
|
||||
count-only-first-join: true
|
||||
require-player-to-stay-online-minutes: 5
|
||||
block-self-referrals: true
|
||||
block-same-ip: true
|
||||
compare-against-referrer-known-ips: true
|
||||
compare-against-other-referred-ips: true
|
||||
store-ip-addresses: true
|
||||
hash-ip-addresses: false
|
||||
|
||||
rewards:
|
||||
milestones:
|
||||
"2":
|
||||
commands:
|
||||
- "say %referrer% reached 2 referrals!"
|
||||
message: "&aYou reached 2 referrals and earned a reward!"
|
||||
"5":
|
||||
commands:
|
||||
- "say %referrer% reached 5 referrals!"
|
||||
message: "&aYou reached 5 referrals and earned a reward!"
|
||||
"10":
|
||||
commands:
|
||||
- "say %referrer% reached 10 referrals!"
|
||||
message: "&6You reached 10 referrals and earned a reward!"
|
||||
|
||||
alerts:
|
||||
notify-on-blocked-same-ip: true
|
||||
notify-permission: "dirtreferrals.alerts"
|
||||
|
||||
database:
|
||||
file: "referrals.db"
|
||||
|
||||
admin:
|
||||
stats-page-size: 10
|
||||
@@ -0,0 +1,26 @@
|
||||
prefix: "&6[DirtReferrals] "
|
||||
|
||||
player-only: "&cPlayers only."
|
||||
no-permission: "&cYou do not have permission."
|
||||
reloaded: "&aDirtReferrals reloaded."
|
||||
unknown-subcommand: "&cUnknown subcommand."
|
||||
usage-admin: "&eUsage: /dirtreferrals <reload|stats|top|give|take>"
|
||||
usage-stats: "&eUsage: /dirtreferrals stats <player>"
|
||||
usage-give: "&eUsage: /dirtreferrals give <player> <amount>"
|
||||
usage-take: "&eUsage: /dirtreferrals take <player> <amount>"
|
||||
|
||||
referral-link: "&aHere is your referral IP! Have your friends join using it to receive rewards: &e%referral_ip%"
|
||||
stats-header: "&6Referral stats for &e%player%&6:"
|
||||
stats-count: "&eCount: &a%count%"
|
||||
top-header: "&6Top Referrals:"
|
||||
top-entry: "&e#%position% &f%player% &7- &a%count%"
|
||||
no-data: "&cNo data found for that player."
|
||||
|
||||
credit-added: "&aAdded &e%amount% &acredit to &e%player%&a."
|
||||
credit-removed: "&aRemoved &e%amount% &acredit from &e%player%&a."
|
||||
not-enough-credit: "&cThat player does not have enough referral credit."
|
||||
invalid-number: "&cInvalid number."
|
||||
blocked-same-ip: "&cReferral blocked due to same IP."
|
||||
blocked-self-referral: "&cYou cannot refer yourself."
|
||||
milestone-reward: "&aYou earned a referral reward for %amount% referrals!"
|
||||
referral-counted: "&aReferral counted for &e%referrer%&a."
|
||||
@@ -0,0 +1,26 @@
|
||||
name: DirtReferrals
|
||||
version: 1.0.0
|
||||
main: com.dirtbagmc.dirtreferrals.DirtReferralsPlugin
|
||||
api-version: '1.21'
|
||||
author: DirtBagMC
|
||||
description: Referral tracking plugin with subdomain-based joins and milestone rewards
|
||||
|
||||
commands:
|
||||
refer:
|
||||
description: Show your referral address
|
||||
usage: /refer
|
||||
aliases: [referrals]
|
||||
dirtreferrals:
|
||||
description: DirtReferrals admin commands
|
||||
usage: /dirtreferrals <reload|stats|top|give|take>
|
||||
|
||||
permissions:
|
||||
dirtreferrals.use:
|
||||
description: Allows use of referral commands
|
||||
default: true
|
||||
dirtreferrals.admin:
|
||||
description: Allows admin commands
|
||||
default: op
|
||||
dirtreferrals.alerts:
|
||||
description: Receive blocked referral alerts
|
||||
default: op
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
domain:
|
||||
base: "dirtbagmc.com"
|
||||
use-lowercase-playernames: true
|
||||
|
||||
referral:
|
||||
count-only-first-join: true
|
||||
require-player-to-stay-online-minutes: 5
|
||||
block-self-referrals: true
|
||||
block-same-ip: true
|
||||
compare-against-referrer-known-ips: true
|
||||
compare-against-other-referred-ips: true
|
||||
store-ip-addresses: true
|
||||
hash-ip-addresses: false
|
||||
|
||||
rewards:
|
||||
milestones:
|
||||
"2":
|
||||
commands:
|
||||
- "say %referrer% reached 2 referrals!"
|
||||
message: "&aYou reached 2 referrals and earned a reward!"
|
||||
"5":
|
||||
commands:
|
||||
- "say %referrer% reached 5 referrals!"
|
||||
message: "&aYou reached 5 referrals and earned a reward!"
|
||||
"10":
|
||||
commands:
|
||||
- "say %referrer% reached 10 referrals!"
|
||||
message: "&6You reached 10 referrals and earned a reward!"
|
||||
|
||||
alerts:
|
||||
notify-on-blocked-same-ip: true
|
||||
notify-permission: "dirtreferrals.alerts"
|
||||
|
||||
database:
|
||||
file: "referrals.db"
|
||||
|
||||
admin:
|
||||
stats-page-size: 10
|
||||
@@ -0,0 +1,26 @@
|
||||
prefix: "&6[DirtReferrals] "
|
||||
|
||||
player-only: "&cPlayers only."
|
||||
no-permission: "&cYou do not have permission."
|
||||
reloaded: "&aDirtReferrals reloaded."
|
||||
unknown-subcommand: "&cUnknown subcommand."
|
||||
usage-admin: "&eUsage: /dirtreferrals <reload|stats|top|give|take>"
|
||||
usage-stats: "&eUsage: /dirtreferrals stats <player>"
|
||||
usage-give: "&eUsage: /dirtreferrals give <player> <amount>"
|
||||
usage-take: "&eUsage: /dirtreferrals take <player> <amount>"
|
||||
|
||||
referral-link: "&aHere is your referral IP! Have your friends join using it to receive rewards: &e%referral_ip%"
|
||||
stats-header: "&6Referral stats for &e%player%&6:"
|
||||
stats-count: "&eCount: &a%count%"
|
||||
top-header: "&6Top Referrals:"
|
||||
top-entry: "&e#%position% &f%player% &7- &a%count%"
|
||||
no-data: "&cNo data found for that player."
|
||||
|
||||
credit-added: "&aAdded &e%amount% &acredit to &e%player%&a."
|
||||
credit-removed: "&aRemoved &e%amount% &acredit from &e%player%&a."
|
||||
not-enough-credit: "&cThat player does not have enough referral credit."
|
||||
invalid-number: "&cInvalid number."
|
||||
blocked-same-ip: "&cReferral blocked due to same IP."
|
||||
blocked-self-referral: "&cYou cannot refer yourself."
|
||||
milestone-reward: "&aYou earned a referral reward for %amount% referrals!"
|
||||
referral-counted: "&aReferral counted for &e%referrer%&a."
|
||||
@@ -0,0 +1,26 @@
|
||||
name: DirtReferrals
|
||||
version: 1.0.0
|
||||
main: com.dirtbagmc.dirtreferrals.DirtReferralsPlugin
|
||||
api-version: '1.21'
|
||||
author: DirtBagMC
|
||||
description: Referral tracking plugin with subdomain-based joins and milestone rewards
|
||||
|
||||
commands:
|
||||
refer:
|
||||
description: Show your referral address
|
||||
usage: /refer
|
||||
aliases: [referrals]
|
||||
dirtreferrals:
|
||||
description: DirtReferrals admin commands
|
||||
usage: /dirtreferrals <reload|stats|top|give|take>
|
||||
|
||||
permissions:
|
||||
dirtreferrals.use:
|
||||
description: Allows use of referral commands
|
||||
default: true
|
||||
dirtreferrals.admin:
|
||||
description: Allows admin commands
|
||||
default: op
|
||||
dirtreferrals.alerts:
|
||||
description: Receive blocked referral alerts
|
||||
default: op
|
||||
@@ -0,0 +1,5 @@
|
||||
#Generated by Maven
|
||||
#Sat Jun 13 18:22:07 EDT 2026
|
||||
artifactId=DirtReferrals
|
||||
groupId=com.dirtbagmc
|
||||
version=1.0.0
|
||||
@@ -0,0 +1,9 @@
|
||||
com/dirtbagmc/dirtreferrals/AdminCommand.class
|
||||
com/dirtbagmc/dirtreferrals/ReferralManager$PendingReferral.class
|
||||
com/dirtbagmc/dirtreferrals/PlayerListener.class
|
||||
com/dirtbagmc/dirtreferrals/DatabaseManager.class
|
||||
com/dirtbagmc/dirtreferrals/MessageManager.class
|
||||
com/dirtbagmc/dirtreferrals/ReferralCommand.class
|
||||
com/dirtbagmc/dirtreferrals/TopEntry.class
|
||||
com/dirtbagmc/dirtreferrals/ReferralManager.class
|
||||
com/dirtbagmc/dirtreferrals/DirtReferralsPlugin.class
|
||||
@@ -0,0 +1,8 @@
|
||||
/home/bitnix/Desktop/DirtRewards/src/main/java/com/dirtbagmc/dirtreferrals/AdminCommand.java
|
||||
/home/bitnix/Desktop/DirtRewards/src/main/java/com/dirtbagmc/dirtreferrals/DatabaseManager.java
|
||||
/home/bitnix/Desktop/DirtRewards/src/main/java/com/dirtbagmc/dirtreferrals/DirtReferralsPlugin.java
|
||||
/home/bitnix/Desktop/DirtRewards/src/main/java/com/dirtbagmc/dirtreferrals/MessageManager.java
|
||||
/home/bitnix/Desktop/DirtRewards/src/main/java/com/dirtbagmc/dirtreferrals/PlayerListener.java
|
||||
/home/bitnix/Desktop/DirtRewards/src/main/java/com/dirtbagmc/dirtreferrals/ReferralCommand.java
|
||||
/home/bitnix/Desktop/DirtRewards/src/main/java/com/dirtbagmc/dirtreferrals/ReferralManager.java
|
||||
/home/bitnix/Desktop/DirtRewards/src/main/java/com/dirtbagmc/dirtreferrals/TopEntry.java
|
||||
Reference in New Issue
Block a user