Merge remote-tracking branch 'refs/remotes/origin/develop' into feature/gem-hunters-persistence

This commit is contained in:
Sam 2017-03-25 14:03:35 +00:00
commit 4455509bc8
21 changed files with 1215 additions and 36 deletions

View File

@ -16,6 +16,7 @@ import java.util.logging.Logger;
import mineplex.bungee.api.ApiDeleteCall;
import mineplex.bungee.api.ApiGetCall;
import mineplex.bungee.api.ApiPostCall;
import mineplex.bungee.api.HttpCallBase;
import mineplex.bungee.api.token.ARecord;
import mineplex.bungee.api.token.DnsRecord;
import mineplex.bungee.api.token.DomainRecords;
@ -24,8 +25,8 @@ import mineplex.serverdata.data.BungeeServer;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ConnectionData;
import mineplex.serverdata.servers.ConnectionData.ConnectionType;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ConnectionData.ConnectionType;
public class BungeeRotator
{
@ -96,8 +97,7 @@ public class BungeeRotator
_repository = new RedisDataRepository<BungeeServer>(ServerManager.getConnection(true, ServerManager.SERVER_STATUS_LABEL), ServerManager.getConnection(false, ServerManager.SERVER_STATUS_LABEL),
Region.ALL, BungeeServer.class, "bungeeServers");
// Temporarily reassigning to US Redis IP for EU player redirection testing. 10.81.1.156 -> 10.33.53.16
_secondRepository = new RedisDataRepository<BungeeServer>(new ConnectionData("10.33.53.16", 6379, ConnectionType.MASTER, "ServerStatus"), new ConnectionData("10.33.53.16", 6377, ConnectionType.SLAVE, "ServerStatus"),
_secondRepository = new RedisDataRepository<BungeeServer>(new ConnectionData("10.81.1.156", 6379, ConnectionType.MASTER, "ServerStatus"), new ConnectionData("10.81.1.156", 6377, ConnectionType.SLAVE, "ServerStatus"),
Region.ALL, BungeeServer.class, "bungeeServers");
//_ipRepository = new PlayerStatsRepository();
@ -110,7 +110,7 @@ public class BungeeRotator
try
{
List<BungeeServer> bungeeServers = new ArrayList<BungeeServer>(_repository.getElements());
//bungeeServers.addAll(_secondRepository.getElements());
bungeeServers.addAll(_secondRepository.getElements());
Collections.sort(bungeeServers, bungeeSorter);

View File

@ -10,58 +10,61 @@ import mineplex.core.common.util.UtilPlayer;
public enum Rank
{
//Staff
LT("Leader", "lt", ChatColor.DARK_RED, "Leaders manage the operation of their respective team \nor projects. They usually operate on affairs within \nthe staff, development, or management team."),
OWNER("Owner", "owner", ChatColor.DARK_RED, "Owners are the founders of Mineplex. \nEach owner manages a different aspect of the \nserver and ensures its efficient operation."),
DEVELOPER("Dev", "dev", ChatColor.DARK_RED, "Developers work behind the scenes to \ncreate new games and features, and fix bugs to \ngive the best experience."),
ADMIN("Admin", "adm", ChatColor.DARK_RED, "An Administrators role is to manage \ntheir respective Senior Moderator team \nand all moderators within it."),
JNR_DEV("Jr.Dev", "jrdev", ChatColor.GOLD, "Junior Developers work behind the scenes to \ncreate new games and features, and fix bugs to \ngive the best experience."),
SUPPORT("Support", "spp", ChatColor.BLUE, "Support agents handle tickets and \nprovide customer service."),
CMOD("C.Mod", "cmod", ChatColor.GOLD, "Clans Moderators are members of the Clans Management Senior Mod team. \nTheir duties include moderation and support within the Clans servers. \n\nFor assistance, contact them using " + F.elem("/a <message>") + "."),
SNR_MODERATOR("Sr.Mod", "srmod", ChatColor.GOLD, "Senior Moderators are members of a special \nSenior Moderator team where they have to fulfill specific tasks. \nJust like Moderators, you can always ask them for help. \n\nFor assistance, contact them using " + F.elem("/a <message>") + "."),
MODERATOR("Mod", "mod", ChatColor.GOLD, "Moderators enforce rules and provide help to \nanyone with questions or concerns. \n\nFor assistance, contact them using " + F.elem("/a <message>") + "."),
HELPER("Trainee", "train", ChatColor.GOLD, "Trainees are moderators-in-training. \nTheir duties include enforcing the rules and \nproviding help to anyone with questions or concerns. \n\nFor assistance, contact them using " + F.elem("/a <message>") + "."),
MAPLEAD("MapLead", "mapl", ChatColor.BLUE, "Map Leaders are leaders of the Mineplex Build Team. \nThey oversee the creation of new maps and manage Builders."),
MAPDEV("Builder", "mapd", ChatColor.BLUE, "Builders are members of the Mineplex Build Team. \nThey create many of the maps used across Mineplex."),
MEDIA("Media", "media", ChatColor.BLUE, "The Media rank is given to talented artists who are\n endorsed to create content for Mineplex."),
LT("Leader", "lt", ChatColor.DARK_RED, "Leaders manage the operation of their respective team \nor projects. They usually operate on affairs within \nthe staff, development, or management team.", 11),
OWNER("Owner", "owner", ChatColor.DARK_RED, "Owners are the founders of Mineplex. \nEach owner manages a different aspect of the \nserver and ensures its efficient operation.", 55),
DEVELOPER("Dev", "dev", ChatColor.DARK_RED, "Developers work behind the scenes to \ncreate new games and features, and fix bugs to \ngive the best experience.", 5),
ADMIN("Admin", "adm", ChatColor.DARK_RED, "An Administrators role is to manage \ntheir respective Senior Moderator team \nand all moderators within it.", 10),
JNR_DEV("Jr.Dev", "jrdev", ChatColor.GOLD, "Junior Developers work behind the scenes to \ncreate new games and features, and fix bugs to \ngive the best experience.", -1),
SUPPORT("Support", "spp", ChatColor.BLUE, "Support agents handle tickets and \nprovide customer service.", 47),
CMOD("C.Mod", "cmod", ChatColor.GOLD, "Clans Moderators are members of the Clans Management Senior Mod team. \nTheir duties include moderation and support within the Clans servers. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 32),
SNR_MODERATOR("Sr.Mod", "srmod", ChatColor.GOLD, "Senior Moderators are members of a special \nSenior Moderator team where they have to fulfill specific tasks. \nJust like Moderators, you can always ask them for help. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 44),
MODERATOR("Mod", "mod", ChatColor.GOLD, "Moderators enforce rules and provide help to \nanyone with questions or concerns. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 32),
HELPER("Trainee", "train", ChatColor.GOLD, "Trainees are moderators-in-training. \nTheir duties include enforcing the rules and \nproviding help to anyone with questions or concerns. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 24),
MAPLEAD("MapLead", "mapl", ChatColor.BLUE, "Map Leaders are leaders of the Mineplex Build Team. \nThey oversee the creation of new maps and manage Builders.", 25),
MAPDEV("Builder", "mapd", ChatColor.BLUE, "Builders are members of the Mineplex Build Team. \nThey create many of the maps used across Mineplex.", 26),
MEDIA("Media", "media", ChatColor.BLUE, "The Media rank is given to talented artists who are\n endorsed to create content for Mineplex.", -1),
EVENT("Event", "evnt", ChatColor.WHITE, "A member of the official Mineplex Events team!"),
EVENT("Event", "evnt", ChatColor.WHITE, "A member of the official Mineplex Events team!", -1),
//Media
YOUTUBE("YouTube", "yt", ChatColor.RED, "A YouTuber who creates content for \nor related to Mineplex."),
YOUTUBE_SMALL("YT", "ytsm", ChatColor.DARK_PURPLE, "A YouTuber who creates content for \nor related to Mineplex. \n\nThey have fewer subscribers than full YouTubers."),
TWITCH("Twitch", "tw", ChatColor.DARK_PURPLE, "A Twitch streamer who often features \nMineplex in their streams."),
YOUTUBE("YouTube", "yt", ChatColor.RED, "A YouTuber who creates content for \nor related to Mineplex.", 22),
YOUTUBE_SMALL("YT", "ytsm", ChatColor.DARK_PURPLE, "A YouTuber who creates content for \nor related to Mineplex. \n\nThey have fewer subscribers than full YouTubers.", 20),
TWITCH("Twitch", "tw", ChatColor.DARK_PURPLE, "A Twitch streamer who often features \nMineplex in their streams.", 21),
//Player
ETERNAL("Eternal", "et", ChatColor.DARK_AQUA, true, "Fantastic and magical, no one \nexcept the time lords truly understand \nthe power of this rank.\n\nThe fifth purchasable rank at Mineplex.com/shop"),
TITAN("Titan", "t", ChatColor.RED, true, "Ancient myths spoke of a gigantic being \nwith immense power... \n\nThe fourth purchasable rank at Mineplex.com/shop"),
LEGEND("Legend", "l", ChatColor.GREEN, true, "Years they have told stories of this rank, \nonly for the legends to be true. \n\nThe third purchasable rank at Mineplex.com/shop"),
HERO("Hero", "h", ChatColor.LIGHT_PURPLE, true, "There are many stories of a \nvaliant Hero who was brave enough to \ntame the most fearsome dragon in the land. \n\nThe second purchasable rank at Mineplex.com/shop"),
ULTRA("Ultra", "u", ChatColor.AQUA, true, "A first step into the stories of the mist. \nOnly those brave enough may enter. \n\nThe first purchasable rank at Mineplex.com/shop"),
ALL("", "", ChatColor.WHITE, null);
ETERNAL("Eternal", "et", ChatColor.DARK_AQUA, true, "Fantastic and magical, no one \nexcept the time lords truly understand \nthe power of this rank.\n\nThe fifth purchasable rank at Mineplex.com/shop", 18),
TITAN("Titan", "t", ChatColor.RED, true, "Ancient myths spoke of a gigantic being \nwith immense power... \n\nThe fourth purchasable rank at Mineplex.com/shop", 15),
LEGEND("Legend", "l", ChatColor.GREEN, true, "Years they have told stories of this rank, \nonly for the legends to be true. \n\nThe third purchasable rank at Mineplex.com/shop", 14),
HERO("Hero", "h", ChatColor.LIGHT_PURPLE, true, "There are many stories of a \nvaliant Hero who was brave enough to \ntame the most fearsome dragon in the land. \n\nThe second purchasable rank at Mineplex.com/shop", 13),
ULTRA("Ultra", "u", ChatColor.AQUA, true, "A first step into the stories of the mist. \nOnly those brave enough may enter. \n\nThe first purchasable rank at Mineplex.com/shop", 12),
ALL("", "", ChatColor.WHITE, null, -1);
private ChatColor _color;
private boolean _donor;
private String _description;
private int _forumId;
public String Name;
public String ScoreboardTag;
Rank(String name, String scoreboardTag, ChatColor color, String description)
Rank(String name, String scoreboardTag, ChatColor color, String description, int forumId)
{
_color = color;
Name = name;
_donor = false;
_description = description;
ScoreboardTag = scoreboardTag;
_forumId = forumId;
}
Rank(String name, String scoreboardTag, ChatColor color, boolean donor, String description)
Rank(String name, String scoreboardTag, ChatColor color, boolean donor, String description, int forumId)
{
_color = color;
Name = name;
_donor = donor;
_description = description;
ScoreboardTag = scoreboardTag;
_forumId = forumId;
}
public String getDescription()
@ -138,4 +141,9 @@ public enum Rank
{
return _donor;
}
}
public int getForumId()
{
return _forumId;
}
}

View File

@ -36,6 +36,7 @@ import mineplex.core.account.command.TestRank;
import mineplex.core.account.command.UpdateRank;
import mineplex.core.account.event.ClientUnloadEvent;
import mineplex.core.account.event.ClientWebResponseEvent;
import mineplex.core.account.event.RankSaveEvent;
import mineplex.core.account.repository.AccountRepository;
import mineplex.core.account.repository.token.ClientToken;
import mineplex.core.common.Rank;
@ -43,6 +44,7 @@ import mineplex.core.common.timing.TimingManager;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UUIDFetcher;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTasks;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@ -552,6 +554,7 @@ public class CoreClientManager extends MiniPlugin
client.SetRank(newRank, false);
}
UtilServer.CallEvent(new RankSaveEvent(uuid, newRank));
}
}, name, uuid, rank, perm);
}
@ -571,6 +574,8 @@ public class CoreClientManager extends MiniPlugin
if (callback != null)
callback.run(newRank);
UtilServer.CallEvent(new RankSaveEvent(uuid, newRank));
}
}, name, uuid, rank, perm);
}

View File

@ -0,0 +1,42 @@
package mineplex.core.account.event;
import java.util.UUID;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import mineplex.core.common.Rank;
public class RankSaveEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private UUID _uuid;
private Rank _rank;
public RankSaveEvent(UUID uuid, Rank rank)
{
_uuid = uuid;
_rank = rank;
}
public UUID getUUID()
{
return _uuid;
}
public Rank getRank()
{
return _rank;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -16,6 +16,7 @@ import com.google.gson.reflect.TypeToken;
import mineplex.cache.player.PlayerCache;
import mineplex.core.account.ILoginProcessor;
import mineplex.core.account.event.RankSaveEvent;
import mineplex.core.account.repository.token.LoginToken;
import mineplex.core.account.repository.token.RankUpdateToken;
import mineplex.core.common.Rank;
@ -204,6 +205,8 @@ public class AccountRepository extends MinecraftRepository
{
if (callback != null)
callback.run(response);
UtilServer.CallEvent(new RankSaveEvent(uuid, rank));
});
};

View File

@ -110,6 +110,7 @@ public abstract class WinEffectGadget extends Gadget
}
finally
{
UtilServer.getPlayersCollection().forEach(UtilPlayer::showForAll);
_player = null;
_baseLocation = null;
_team.clear();

View File

@ -0,0 +1,44 @@
package mineplex.core.powerplayclub;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class PPCDataRequestEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Player _player;
private PowerPlayData _data;
public PPCDataRequestEvent(Player player)
{
_player = player;
_data = null;
}
public Player getPlayer()
{
return _player;
}
public PowerPlayData getData()
{
return _data;
}
public void setData(PowerPlayData data)
{
_data = data;;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -25,6 +25,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.account.ILoginProcessor;
import mineplex.core.common.util.UtilServer;
import mineplex.core.donation.DonationManager;
import mineplex.serverdata.database.DBPool;
@ -120,9 +121,17 @@ public class PowerPlayClubRepository implements Listener {
_stageOneDataClaims.remove(event.getPlayer().getUniqueId()); // Just in case.
_cachedPlayerData.remove(event.getPlayer().getUniqueId());
}
@EventHandler
public void onDataRequested(PPCDataRequestEvent event)
{
event.setData(getCachedData(event.getPlayer()));
}
public CompletableFuture<Void> addSubscription(int accountId, LocalDate date, String duration)
{
UtilServer.CallEvent(new SubscriptionAddEvent(accountId, duration));
return CompletableFuture.supplyAsync(() ->
{
try (Connection connection = DBPool.getAccount().getConnection())
@ -133,7 +142,8 @@ public class PowerPlayClubRepository implements Listener {
statement.setString(3, duration);
statement.executeUpdate();
} catch (SQLException e)
}
catch (SQLException e)
{
e.printStackTrace();
}

View File

@ -0,0 +1,38 @@
package mineplex.core.powerplayclub;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class SubscriptionAddEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private int _accountId;
private String _duration;
public SubscriptionAddEvent(int accountId, String duration)
{
_accountId = accountId;
_duration = duration;
}
public int getAccountId()
{
return _accountId;
}
public String getDuration()
{
return _duration;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,15 @@
package mineplex.core.website;
public class ForumUserData
{
public boolean Linked;
public int LinkedForumId;
public boolean LastSyncedPowerPlayStatus;
public ForumUserData()
{
Linked = false;
LinkedForumId = -1;
LastSyncedPowerPlayStatus = false;
}
}

View File

@ -0,0 +1,36 @@
package mineplex.core.website;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
public class LinkCommand extends CommandBase<WebsiteLinkManager>
{
public LinkCommand(WebsiteLinkManager plugin)
{
super(plugin, Rank.ALL, "link");
}
@Override
public void Execute(final Player caller, String[] args)
{
if (args.length < 1)
{
//UtilPlayer.message(caller, F.help("/" + _aliasUsed + " XXX-XXX-XXX", "Begins linking your Minecraft account with your website link code.", Rank.ALL, ChatColor.GREEN));
}
else
{
if (Plugin.Get(caller).Linked)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "Your account is already linked!"));
}
else
{
Plugin.startLink(caller, args[0]);
}
}
}
}

View File

@ -0,0 +1,28 @@
package mineplex.core.website;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
public class MineplexAuthenticator extends Authenticator
{
private String _username, _password;
public MineplexAuthenticator(String username, String password)
{
_username = username;
_password = password;
}
@Override
public PasswordAuthentication getPasswordAuthentication()
{
System.out.println("-==Mineplex Authentication In Progress==-");
System.out.println("Requesting Host: " + getRequestingHost());
System.out.println("Requesting Port: " + getRequestingPort());
System.out.println("Requesting Prompt: " + getRequestingPrompt());
System.out.println("Requesting Protocol: " + getRequestingProtocol());
System.out.println("Requesting Scheme: " + getRequestingScheme());
System.out.println("Requesting Site: " + getRequestingSite());
return new PasswordAuthentication(_username, _password.toCharArray());
}
}

View File

@ -0,0 +1,27 @@
package mineplex.core.website;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
public class UnlinkCommand extends CommandBase<WebsiteLinkManager>
{
public UnlinkCommand(WebsiteLinkManager plugin)
{
super(plugin, Rank.ADMIN, "unlink");
}
@Override
public void Execute(final Player caller, String[] args)
{
if (args.length < 1)
{
//UtilPlayer.message(caller, F.help("/" + _aliasUsed + " <Player>", "Removes a link to a forum and in-game account.", Rank.ADMIN, ChatColor.RED));
}
else
{
Plugin.unlink(caller, args[0]);
}
}
}

View File

@ -0,0 +1,834 @@
package mineplex.core.website;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import mineplex.core.MiniDbClientPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.account.event.RankSaveEvent;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.powerplayclub.PPCDataRequestEvent;
import mineplex.core.powerplayclub.PowerPlayData;
import mineplex.core.powerplayclub.SubscriptionAddEvent;
import mineplex.serverdata.database.DBPool;
public class WebsiteLinkManager extends MiniDbClientPlugin<ForumUserData>
{
private final JsonParser PARSER = new JsonParser();
private final String API_URL = "https://xen.mineplex.com/api.php";
private final String API_KEY = "dd412425-edb0-477c-abee-2d0b507c59ef";
private final int POWER_PLAY_TAG_ID = 17;
private final int LINKED_TAG_ID = 91;
public WebsiteLinkManager(JavaPlugin plugin, CoreClientManager clientManager)
{
super("Website Link", plugin, clientManager);
addCommand(new LinkCommand(this));
addCommand(new UnlinkCommand(this));
Authenticator.setDefault(new MineplexAuthenticator("minexen", "c4cADuj&ChaQ"));
}
public void unlink(Player sender, String target)
{
getClientManager().getOrLoadClient(target, client ->
{
if (client != null)
{
Consumer<ForumUserData> dataCallback = data ->
{
if (data == null)
{
UtilPlayer.message(sender, F.main(getName(), "Could not find " + F.name(target) + "!"));
}
else
{
if (!data.Linked)
{
UtilPlayer.message(sender, F.main(getName(), F.name(target) + " is not linked to a forum account!"));
}
else
{
runAsync(() ->
{
loadXenforoAccount(data.LinkedForumId, user ->
{
List<Integer> remove = new ArrayList<>();
remove.add(POWER_PLAY_TAG_ID);
remove.add(LINKED_TAG_ID);
for (Rank rank : Rank.values())
{
if (rank.getForumId() != -1)
{
remove.add(rank.getForumId());
}
}
String call = "action=editUser&user=" + user.username + "&custom_fields=mcAcctIdPC=";
doAPICall(call, err ->
{
runSync(() -> UtilPlayer.message(sender, F.main(getName(), F.name(target) + " was not able to be unlinked at this time!")));
}, () ->
{
runSync(() -> UtilPlayer.message(sender, F.main(getName(), F.name(target) + " was not able to be unlinked at this time!")));
}, () ->
{
refreshSiteTags(data.LinkedForumId, remove, new ArrayList<>(), false, () ->
{
try (Connection c = DBPool.getAccount().getConnection())
{
c.prepareStatement("DELETE FROM forumLink WHERE accountId=" + client.getAccountId()).execute();
runSync(() ->
{
UtilPlayer.message(sender, F.main(getName(), F.name(target) + " was successfully unlinked!"));
data.Linked = false;
data.LinkedForumId = -1;
data.LastSyncedPowerPlayStatus = false;
});
}
catch (SQLException e)
{
e.printStackTrace();
runSync(() -> UtilPlayer.message(sender, F.main(getName(), F.name(target) + " was not able to be unlinked at this time!")));
}
}, false, () -> UtilPlayer.message(sender, F.main(getName(), F.name(target) + " was not able to be unlinked at this time!")), true);
});
});
});
}
}
};
if (Bukkit.getPlayer(client.getUniqueId()) != null)
{
dataCallback.accept(Get(client.getUniqueId()));
}
else
{
runAsync(() ->
{
try (Connection c = DBPool.getAccount().getConnection())
{
ResultSet rs = c.prepareStatement("SELECT userId, powerPlayStatus FROM forumLink WHERE accountId=" + client.getAccountId() + ";").executeQuery();
if (rs.next())
{
Integer userId = rs.getInt(1);
Boolean powerPlay = rs.getBoolean(2);
final ForumUserData data = new ForumUserData();
data.Linked = true;
data.LinkedForumId = userId;
data.LastSyncedPowerPlayStatus = powerPlay;
runSync(() -> dataCallback.accept(data));
}
else
{
runSync(() -> dataCallback.accept(new ForumUserData()));
}
}
catch (SQLException e)
{
e.printStackTrace();
runSync(() -> dataCallback.accept(new ForumUserData()));
}
});
}
}
else
{
UtilPlayer.message(sender, F.main(getName(), "Could not find " + F.name(target) + "!"));
}
});
}
public void startLink(Player player, String code)
{
final int forumId = getForumId(code);
final int accountId = getClientManager().getAccountId(player);
final Rank rank = getClientManager().Get(player).GetRank(true);
PowerPlayData d = UtilServer.CallEvent(new PPCDataRequestEvent(player)).getData();
final boolean powerPlay = (d != null && d.isSubscribed());
if (forumId == -1)
{
UtilPlayer.message(player, F.main(getName(), "That link code is invalid!"));
return;
}
runAsync(() ->
{
loadXenforoAccount(forumId, data ->
{
if (data == null)
{
UtilPlayer.message(player, F.main(getName(), "That link code is invalid!"));
return;
}
if (data.custom_fields.containsKey("mcAcctIdPC") && !data.custom_fields.get("mcAcctIdPC").isEmpty())
{
UtilPlayer.message(player, F.main(getName(), "That link code is invalid!"));
return;
}
completeLink(player, data, accountId, rank, powerPlay);
});
});
}
private void completeLink(Player player, XenForoData data, int accountId, Rank rank, boolean powerPlay)
{
try (Connection c = DBPool.getAccount().getConnection())
{
boolean success = c.prepareStatement("INSERT INTO forumLink (accountId, userId, powerPlayStatus) VALUES (" + accountId + ", " + data.user_id + ", " + powerPlay + ");").executeUpdate() > 0;
if (success)
{
String call = "action=editUser&user=" + data.username + "&custom_fields=mcAcctIdPC=" + accountId;
List<Integer> adding = new ArrayList<>();
adding.add(91);
if (rank.getForumId() != -1)
{
adding.add(rank.getForumId());
}
if (powerPlay)
{
adding.add(POWER_PLAY_TAG_ID);
}
doAPICall(call, err ->
{
runSync(() -> UtilPlayer.message(player, F.main(getName(), "The link failed! Please try again!")));
}, () ->
{
runSync(() -> UtilPlayer.message(player, F.main(getName(), "The link failed! Please try again!")));
}, () ->
{
refreshSiteTags(data, new ArrayList<>(), adding, false, () ->
{
UtilPlayer.message(player, F.main(getName(), "You have successfully linked your account!"));
if (player.isOnline())
{
Get(player).LinkedForumId = data.user_id;
Get(player).LastSyncedPowerPlayStatus = powerPlay;
Get(player).Linked = true;
}
}, true, () -> UtilPlayer.message(player, F.main(getName(), "The link failed! Please try again!")), true);
});
}
else
{
runSync(() -> UtilPlayer.message(player, F.main(getName(), "The link failed! Please try again!")));
}
}
catch (SQLException e)
{
runSync(() -> UtilPlayer.message(player, F.main(getName(), "The link failed! Please try again!")));
e.printStackTrace();
}
}
private void refreshSiteTags(int userId, List<Integer> removing, List<Integer> adding, boolean runAsync, Runnable after, boolean runAfterSync, Runnable onErr, boolean runErrSync)
{
Runnable r = () ->
{
loadXenforoAccount(userId, data ->
{
refreshSiteTags(data, removing, adding, false, after, runAfterSync, onErr, runErrSync);
});
};
if (runAsync)
{
runAsync(r);
}
else
{
r.run();
}
}
private void refreshSiteTags(XenForoData data, List<Integer> removing, List<Integer> adding, boolean runAsync, Runnable after, boolean runAfterSync, Runnable onErr, boolean runErrSync)
{
Runnable r = () ->
{
if (data == null)
{
return;
}
String callBase = "action=editUser&user=" + data.username;
String groups = "";
for (int groupId : data.secondary_group_ids)
{
if (!removing.contains(groupId) && !adding.contains(groupId))
{
groups += ("," + groupId);
}
}
for (Integer groupId : adding)
{
groups += ("," + groupId);
}
if (!groups.isEmpty())
{
groups = groups.substring(1);
}
final String addGroups = groups;
groups = "";
for (int groupId : data.secondary_group_ids)
{
groups += ("," + groupId);
}
if (!groups.isEmpty())
{
groups = groups.substring(1);
}
final String remGroups = groups;
if (!remGroups.isEmpty())
{
doAPICall(callBase + "&remove_groups=" + remGroups, err ->
{
if (runErrSync)
{
runSync(onErr);
}
else
{
onErr.run();
}
}, () ->
{
if (runErrSync)
{
runSync(onErr);
}
else
{
onErr.run();
}
}, () ->
{
if (!addGroups.isEmpty())
{
doAPICall(callBase + "&add_groups=" + addGroups, err ->
{
if (runErrSync)
{
runSync(onErr);
}
else
{
onErr.run();
}
}, () ->
{
if (runErrSync)
{
runSync(onErr);
}
else
{
onErr.run();
}
}, () ->
{
if (runAfterSync)
{
runSync(after);
}
else
{
after.run();
}
});
}
else
{
if (runAfterSync)
{
runSync(after);
}
else
{
after.run();
}
}
});
}
else
{
if (!addGroups.isEmpty())
{
doAPICall(callBase + "&add_groups=" + addGroups, err ->
{
if (runErrSync)
{
runSync(onErr);
}
else
{
onErr.run();
}
}, () ->
{
if (runErrSync)
{
runSync(onErr);
}
else
{
onErr.run();
}
}, () ->
{
if (runAfterSync)
{
runSync(after);
}
else
{
after.run();
}
});
}
else
{
if (runAfterSync)
{
runSync(after);
}
else
{
after.run();
}
}
}
};
if (runAsync)
{
runAsync(r);
}
else
{
r.run();
}
}
private void loadXenforoAccount(int userId, Consumer<XenForoData> callback)
{
try
{
StringBuilder result = new StringBuilder();
URL call = new URL(API_URL + "?hash=" + API_KEY + "&action=getUser&value=" + userId);
BufferedReader br = new BufferedReader(new InputStreamReader(call.openStream()));
br.lines().forEach(line -> result.append(line));
String json = result.toString().trim();
JsonObject response = null;
try
{
response = PARSER.parse(json).getAsJsonObject();
if (response.has("error"))
{
callback.accept(null);
}
else
{
XenForoData data = new XenForoData();
data.user_id = response.get("user_id").getAsInt();
data.username = response.get("username").getAsString();
data.email = response.get("email").getAsString();
data.user_group_id = response.get("user_group_id").getAsInt();
String groups = response.get("secondary_group_ids").getAsString();
if (groups.isEmpty())
{
data.secondary_group_ids = new int[] {};
}
else
{
String[] groupIds = groups.split(",");
data.secondary_group_ids = new int[groupIds.length];
for (int index = 0; index < groupIds.length; index++)
{
data.secondary_group_ids[index] = Integer.parseInt(groupIds[index]);
}
}
Map<String, String> fields = new HashMap<>();
if (response.get("custom_fields") instanceof JsonObject)
{
JsonObject cFields = (JsonObject) response.get("custom_fields");
for (Entry<String, JsonElement> entry : cFields.entrySet())
{
fields.put(entry.getKey(), entry.getValue().getAsString());
}
}
data.custom_fields = fields;
callback.accept(data);
}
}
catch (JsonSyntaxException e)
{
callback.accept(null);
e.printStackTrace();
return;
}
}
catch (MalformedURLException e)
{
callback.accept(null);
e.printStackTrace();
}
catch (IOException e)
{
callback.accept(null);
e.printStackTrace();
}
}
private void doAPICall(String call, Consumer<String> errorCallback, Runnable ioException, Runnable onComplete)
{
StringBuilder input = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(API_URL + "?hash=" + API_KEY + "&" + call).openStream())))
{
reader.lines().forEach(l -> input.append(l));
}
catch (IOException e)
{
System.out.println("[XENFORO API] Could not connect to web server");
e.printStackTrace();
ioException.run();
return;
}
JsonObject response = null;
try
{
response = PARSER.parse(input.toString().trim()).getAsJsonObject();
}
catch (JsonSyntaxException e)
{
System.out.println("[XENFORO API] Could not parse JSON response data");
e.printStackTrace();
return;
}
if (response.has("error"))
{
if (response.get("error").getAsString().equals("7"))
{
if (response.has("user_error_id"))
{
String errorID = response.get("user_error_id").getAsString();
errorCallback.accept(errorID);
System.out.println("[XENFORO API] An error was found in the JSON response (id: " + errorID + ") from REST call: " + call);
return;
}
else
{
System.out.println("[XENFORO API] An error was found in the JSON response, but no error code was found from REST call: " + call);
}
}
else
{
System.out.println("[XENFORO API] A non-user error was found in the JSON response (id: " + response.get("error").getAsString() + ") from REST call: " + call);
return;
}
}
else
{
onComplete.run();
}
}
private int getForumId(String linkCode)
{
String given = linkCode.replace("-", "");
if (given.length() < 9)
{
return -1;
}
if (!StringUtils.isNumeric(given))
{
return -1;
}
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
int offset = 100000000;
StringBuilder sb = new StringBuilder(cal.get(Calendar.DAY_OF_YEAR) + "");
while (sb.length() < 3)
{
sb.insert(0, "0");
}
String reverse = sb.reverse().toString();
Integer test = Integer.parseInt(reverse + reverse + reverse);
test += offset;
Integer input = Integer.parseInt(given);
Integer abs = Math.abs(test - input);
// Bukkit.broadcastMessage("REVERSE: " + reverse);
// Bukkit.broadcastMessage("TEST: " + test);
// Bukkit.broadcastMessage("INPUT: " + input);
// Bukkit.broadcastMessage("ABS: " + abs);
// Bukkit.broadcastMessage("MODULUS: " + abs % 11);
if (abs % 11 != 0)
{
return -1;
}
return abs / 11;
}
private void checkAccountOnline(int accountId, BiConsumer<Boolean, UUID> consumer)
{
for (Player player : Bukkit.getOnlinePlayers())
{
if (getClientManager().getAccountId(player) == accountId)
{
consumer.accept(true, player.getUniqueId());
return;
}
}
consumer.accept(false, null);
}
@EventHandler
public void handleRankSave(RankSaveEvent event)
{
Consumer<Integer> dataCallback = id ->
{
List<Integer> remove = new ArrayList<>();
List<Integer> add = new ArrayList<>();
for (Rank rank : Rank.values())
{
if (rank.getForumId() != -1 && rank != event.getRank())
{
remove.add(rank.getForumId());
}
}
if (event.getRank().getForumId() != -1)
{
add.add(event.getRank().getForumId());
}
refreshSiteTags(id, remove, add, false, () -> {}, false, () -> {}, false);
};
if (Bukkit.getPlayer(event.getUUID()) != null)
{
ForumUserData fd = Get(event.getUUID());
if (fd.Linked)
{
final int userId = fd.LinkedForumId;
runAsync(() ->
{
dataCallback.accept(userId);
});
}
}
else
{
runAsync(() ->
{
getClientManager().getRepository().getAccountId(event.getUUID(), accountId ->
{
runAsync(() ->
{
try (Connection c = DBPool.getAccount().getConnection())
{
ResultSet rs = c.prepareStatement("SELECT userId FROM forumLink WHERE accountId=" + accountId + ";").executeQuery();
if (rs.next())
{
Integer userId = rs.getInt(1);
dataCallback.accept(userId);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
});
});
});
}
}
@EventHandler
public void handleSubscriptionAdd(SubscriptionAddEvent event)
{
checkAccountOnline(event.getAccountId(), (online, uuid) ->
{
if (online)
{
ForumUserData fd = Get(uuid);
if (fd.Linked && !fd.LastSyncedPowerPlayStatus)
{
final int userId = fd.LinkedForumId;
runAsync(() ->
{
List<Integer> add = new ArrayList<>();
add.add(POWER_PLAY_TAG_ID);
refreshSiteTags(userId, new ArrayList<>(), add, false, () ->
{
runSync(() ->
{
fd.LastSyncedPowerPlayStatus = true;
});
try (Connection c = DBPool.getAccount().getConnection())
{
c.prepareStatement("UPDATE forumLink SET powerPlayStatus=true WHERE accountId=" + event.getAccountId() + ";").execute();
}
catch (SQLException e)
{
e.printStackTrace();
}
}, false, () -> {}, false);
});
}
}
else
{
runAsync(() ->
{
try (Connection c = DBPool.getAccount().getConnection())
{
ResultSet rs = c.prepareStatement("SELECT userId FROM forumLink WHERE accountId=" + event.getAccountId() + ";").executeQuery();
if (rs.next())
{
Integer userId = rs.getInt(1);
List<Integer> add = new ArrayList<>();
add.add(17);
refreshSiteTags(userId, new ArrayList<>(), add, false, () ->
{
try
{
c.prepareStatement("UPDATE forumLink SET powerPlayStatus=true WHERE accountId=" + event.getAccountId() + ";").execute();
}
catch (SQLException e)
{
e.printStackTrace();
}
}, false, () -> {}, false);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
});
}
});
}
@EventHandler
public void updatePPCTag(PlayerJoinEvent event)
{
runSyncLater(() ->
{
if (event.getPlayer().isOnline())
{
boolean ppc = false;
PowerPlayData d = UtilServer.CallEvent(new PPCDataRequestEvent(event.getPlayer())).getData();
if (d != null)
{
ppc = d.isSubscribed();
final boolean powerPlay = ppc;
if (Get(event.getPlayer()).Linked && Get(event.getPlayer()).LastSyncedPowerPlayStatus != powerPlay)
{
final int userId = Get(event.getPlayer()).LinkedForumId;
final int accountId = getClientManager().getAccountId(event.getPlayer());
runAsync(() ->
{
List<Integer> remove = new ArrayList<>();
List<Integer> add = new ArrayList<>();
if (powerPlay)
{
add.add(POWER_PLAY_TAG_ID);
}
else
{
remove.add(POWER_PLAY_TAG_ID);
}
refreshSiteTags(userId, remove, add, false, () ->
{
runSync(() ->
{
if (event.getPlayer().isOnline())
{
Get(event.getPlayer()).LastSyncedPowerPlayStatus = powerPlay;
}
});
try (Connection c = DBPool.getAccount().getConnection())
{
c.prepareStatement("UPDATE forumLink SET powerPlayStatus=" + powerPlay + " WHERE accountId=" + accountId + ";").execute();
}
catch (SQLException e)
{
e.printStackTrace();
}
}, false, () -> {}, false);
});
}
}
}
}, 40L);
}
@Override
public String getQuery(int accountId, String uuid, String name)
{
return "SELECT userId, powerPlayStatus FROM forumLink WHERE accountId=" + accountId + ";";
}
@Override
public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException
{
if (resultSet.next())
{
ForumUserData data = new ForumUserData();
data.Linked = true;
data.LinkedForumId = resultSet.getInt(1);
data.LastSyncedPowerPlayStatus = resultSet.getBoolean(2);
Set(uuid, data);
}
else
{
Set(uuid, new ForumUserData());
}
}
@Override
protected ForumUserData addPlayer(UUID uuid)
{
return new ForumUserData();
}
}

View File

@ -0,0 +1,13 @@
package mineplex.core.website;
import java.util.Map;
public class XenForoData
{
public int user_id;
public String username;
public String email;
public int user_group_id;
public int[] secondary_group_ids;
public Map<String, String> custom_fields;
}

View File

@ -60,6 +60,7 @@ import mineplex.core.updater.FileUpdater;
import mineplex.core.updater.Updater;
import mineplex.core.velocity.VelocityFix;
import mineplex.core.visibility.VisibilityManager;
import mineplex.core.website.WebsiteLinkManager;
import mineplex.minecraft.game.core.combat.CombatManager;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
@ -181,6 +182,7 @@ public class ClansHub extends JavaPlugin
require(TrackManager.class);
require(Titles.class);
require(TwoFactorAuth.class);
new WebsiteLinkManager(this, clientManager);
}
@Override

View File

@ -1,5 +1,7 @@
package mineplex.hub;
import static mineplex.core.Managers.require;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -74,6 +76,7 @@ import mineplex.core.updater.FileUpdater;
import mineplex.core.updater.Updater;
import mineplex.core.velocity.VelocityFix;
import mineplex.core.visibility.VisibilityManager;
import mineplex.core.website.WebsiteLinkManager;
import mineplex.hub.modules.BillboardManager;
import mineplex.hub.queue.QueueManager;
import mineplex.hub.server.ServerManager;
@ -88,8 +91,6 @@ import mineplex.minecraft.game.core.combat.CombatManager;
import mineplex.minecraft.game.core.damage.DamageManager;
import mineplex.minecraft.game.core.fire.Fire;
import static mineplex.core.Managers.require;
public class Hub extends JavaPlugin implements IRelation
{
private NpcManager _npcManager;
@ -236,6 +237,7 @@ public class Hub extends JavaPlugin implements IRelation
require(Titles.class);
require(TwoFactorAuth.class);
require(TeamspeakManager.class);
new WebsiteLinkManager(this, clientManager);
}
@Override

View File

@ -33,6 +33,9 @@ public class ServerNpcShop extends ShopBase<ServerManager>
case "MS":
return new MinestrikeServerTypePage(getPlugin(), this, getClientManager(), getDonationManager(), player, _serverGroup);
case "UHC":
return new UHCServerTypePage(getPlugin(), this, getClientManager(), getDonationManager(), player);
default:
return new ServerNpcPage(getPlugin(), this, getClientManager(), getDonationManager(), _serverGroup.getServerNpcName(), player, _serverGroup.getPrefix());
}

View File

@ -0,0 +1,66 @@
package mineplex.hub.server.ui;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.hub.server.ServerManager;
public class UHCServerTypePage extends ShopPageBase<ServerManager, ServerNpcShop>
{
public UHCServerTypePage(ServerManager plugin, ServerNpcShop shop, CoreClientManager clientManager,
DonationManager donationManager, Player player)
{
super(plugin, shop, clientManager, donationManager, "Ultra Hardcore", player, 27);
buildPage();
}
@Override
protected void buildPage()
{
setItem(10, new ItemBuilder(Material.SKULL_ITEM, 1, (byte) 3).setTitle(C.Reset + C.cYellow + "UHC Solo")
.addLore(new String[]
{
C.Reset + "",
C.Reset + C.cGreen + "Click to Play",
}).build());
setItem(12, new ItemBuilder(Material.SKULL_ITEM, 2, (byte) 3).setTitle(C.Reset + C.cYellow + "UHC Teams")
.addLore(new String[]
{
C.Reset + "",
C.Reset + C.cGreen + "Click to Play",
}).build());
setItem(14, new ItemBuilder(Material.SKULL_ITEM, 1, (byte) 3).setTitle(C.Reset + C.cYellow + "UHC Speed Solo")
.addLore(new String[]
{
C.Reset + "",
C.Reset + C.cGreen + "Click to Play"
}).build());
setItem(16, new ItemBuilder(Material.SKULL_ITEM, 2, (byte) 3).setTitle(C.Reset + C.cYellow + "UHC Speed Teams")
.addLore(new String[]
{
C.Reset + "",
C.Reset + C.cGreen + "Click to Play"
}).build());
getButtonMap().put(10, (player, __) -> getShop().openPageForPlayer(player, new ServerNpcPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), "UHC Solo", player, "UHC2")));
getButtonMap().put(12, (player, __) -> getShop().openPageForPlayer(player, new ServerNpcPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), "UHC", player, "UHC")));
getButtonMap().put(14, (player, __) -> getShop().openPageForPlayer(player, new ServerNpcPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), "UHC Speed Solo", player, "UHCS2")));
getButtonMap().put(16, (player, __) -> getShop().openPageForPlayer(player, new ServerNpcPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), "UHC Speed", player, "UHCS")));
}
public void Update()
{
getButtonMap().clear();
buildPage();
}
}

View File

@ -73,6 +73,7 @@ import mineplex.core.updater.FileUpdater;
import mineplex.core.updater.Updater;
import mineplex.core.velocity.VelocityFix;
import mineplex.core.visibility.VisibilityManager;
import mineplex.core.website.WebsiteLinkManager;
import mineplex.minecraft.game.core.combat.CombatManager;
import mineplex.minecraft.game.core.damage.DamageManager;
@ -199,6 +200,7 @@ public class Arcade extends JavaPlugin
new FoodDupeFix(this);
require(TwoFactorAuth.class);
new WebsiteLinkManager(this, _clientManager);
//Updates
getServer().getScheduler().scheduleSyncRepeatingTask(this, new Updater(this), 1, 1);

View File

@ -4,6 +4,8 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@ -39,7 +41,6 @@ import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.quest.command.ResetQuestsCommand;
import mineplex.gemhunters.quest.types.ChestOpenerQuest;
import mineplex.gemhunters.quest.types.CraftingQuest;
import mineplex.gemhunters.quest.types.EnjoyTheViewQuest;
import mineplex.gemhunters.quest.types.GiveItemQuest;
import mineplex.gemhunters.quest.types.KillMostValuableQuest;
@ -49,7 +50,6 @@ import mineplex.gemhunters.quest.types.SamitoDQuest;
import mineplex.gemhunters.quest.types.SpecificChestOpenerQuest;
import mineplex.gemhunters.quest.types.WalkingQuest;
import mineplex.gemhunters.world.WorldDataModule;
import net.md_5.bungee.api.ChatColor;
@ReflectivelyCreateMiniPlugin
public class QuestModule extends MiniClientPlugin<QuestPlayerData>
@ -89,7 +89,7 @@ public class QuestModule extends MiniClientPlugin<QuestPlayerData>
new KillMostValuableQuest(17, "Equality", "Slay the most valuable player in the game.", 100, 1500),
new CraftingQuest(18, "Light em up", "Craft " + F.count("5 Torches"), 25, 250, Material.TORCH, 5)
//new CraftingQuest(18, "Light em up", "Craft " + F.count("5 Torches"), 25, 250, Material.TORCH, 5)
};
private final EconomyModule _economy;