Added command queueing for failed commands in EnjinTranslator.

Added verification of coin/gem application in Web api.

Added code to support polling last 100 purchases with EnjinTranslator

Added UUId lookup to CoreClientManager and fixed Async to Async calls with DatabaseRunnable.
This commit is contained in:
Jonathan Williams 2014-11-17 14:06:38 -08:00
parent 2384b91b06
commit 13ba32f2f4
11 changed files with 603 additions and 316 deletions

View File

@ -401,6 +401,12 @@ public class CoreClientManager extends MiniPlugin
}, playerName);
}
// DONT USE THIS IN PRODUCTION...its for enjin listener -someone you despise but definitely not me (defek7)
public UUID loadUUIDFromDB(String name)
{
return _repository.getClientUUID(name);
}
@EventHandler
public void cleanGlitchedClients(UpdateEvent event)
{

View File

@ -1,9 +1,13 @@
package mineplex.core.account.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.libs.com.google.gson.reflect.TypeToken;
import org.bukkit.plugin.java.JavaPlugin;
@ -14,6 +18,7 @@ import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UUIDFetcher;
import mineplex.core.database.DatabaseRunnable;
import mineplex.core.database.RepositoryBase;
import mineplex.core.database.ResultSetCallable;
import mineplex.core.database.column.ColumnBoolean;
import mineplex.core.database.column.ColumnTimestamp;
import mineplex.core.database.column.ColumnVarChar;
@ -30,6 +35,8 @@ public class AccountRepository extends RepositoryBase
private static String UPDATE_ACCOUNT_RANK_DONOR_PERM = "UPDATE accounts SET rank=?, donorRank=?, rankPerm=true WHERE uuid = ?;";
private static String UPDATE_ACCOUNT_NULL_RANK = "UPDATE accounts SET rank=?, donorRank=?, rankPerm=?, rankExpire=? WHERE uuid = ? AND rank IS NULL;";
private static String SELECT_ACCOUNT_UUID_BY_NAME = "SELECT uuid FROM accounts WHERE name = ?;";
private String _webAddress;
public AccountRepository(JavaPlugin plugin, String webAddress)
@ -68,6 +75,28 @@ public class AccountRepository extends RepositoryBase
return new JsonWebCall(_webAddress + "PlayerAccount/GetAccountByUUID").ExecuteReturnStream(uuid.toString());
}
public UUID getClientUUID(String name)
{
final List<UUID> uuids = new ArrayList<UUID>();
executeQuery(SELECT_ACCOUNT_UUID_BY_NAME, new ResultSetCallable()
{
@Override
public void processResultSet(ResultSet resultSet) throws SQLException
{
while (resultSet.next())
{
uuids.add(UUID.fromString(resultSet.getString(1)));
}
}
}, new ColumnVarChar("name", 100, name));
if (uuids.size() > 1)
return null;
else
return uuids.size() == 1 ? uuids.get(0) : null;
}
public void saveRank(final Callback<Rank> callback, final String name, final Rank rank, final boolean perm)
{
final RankUpdateToken token = new RankUpdateToken();
@ -77,7 +106,7 @@ public class AccountRepository extends RepositoryBase
final Callback<Rank> extraCallback = new Callback<Rank>()
{
public void run(Rank response)
public void run(final Rank response)
{
if (rank == Rank.ULTRA || rank == Rank.HERO)
{
@ -94,8 +123,15 @@ public class AccountRepository extends RepositoryBase
executeUpdate(UPDATE_ACCOUNT_RANK, new ColumnVarChar("rank", 100, rank.toString()), new ColumnVarChar("uuid", 100, UUIDFetcher.getUUIDOf(name).toString()));
}
Bukkit.getServer().getScheduler().runTask(Plugin, new Runnable()
{
@Override
public void run()
{
callback.run(response);
}
});
}
};
handleDatabaseCall(new DatabaseRunnable(new Runnable()

View File

@ -2,6 +2,7 @@ package mineplex.core.donation.repository;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.util.Callback;
@ -45,13 +46,20 @@ public class DonationRepository extends RepositoryBase
final Callback<TransactionResponse> extraCallback = new Callback<TransactionResponse>()
{
public void run(TransactionResponse response)
public void run(final TransactionResponse response)
{
if (response == TransactionResponse.Success)
executeUpdate(UPDATE_ACCOUNT_GEMS, new ColumnInt("gems", cost), new ColumnVarChar("uuid", 100, uuid));
Bukkit.getServer().getScheduler().runTask(Plugin, new Runnable()
{
@Override
public void run()
{
callback.run(response);
}
});
}
};
handleDatabaseCall(new DatabaseRunnable(new Runnable()
@ -74,7 +82,7 @@ public class DonationRepository extends RepositoryBase
final Callback<TransactionResponse> extraCallback = new Callback<TransactionResponse>()
{
public void run(TransactionResponse response)
public void run(final TransactionResponse response)
{
if (response == TransactionResponse.Success)
{
@ -90,8 +98,15 @@ public class DonationRepository extends RepositoryBase
}
}
Bukkit.getServer().getScheduler().runTask(Plugin, new Runnable()
{
@Override
public void run()
{
callback.run(response);
}
});
}
};
handleDatabaseCall(new DatabaseRunnable(new Runnable()
@ -112,7 +127,7 @@ public class DonationRepository extends RepositoryBase
final Callback<Boolean> extraCallback = new Callback<Boolean>()
{
public void run(Boolean response)
public void run(final Boolean response)
{
if (response)
{
@ -120,8 +135,15 @@ public class DonationRepository extends RepositoryBase
executeUpdate(INSERT_GEM_TRANSACTION, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("reason", 100, "Given by " + giver), new ColumnInt("gems", greenGems));
}
Bukkit.getServer().getScheduler().runTask(Plugin, new Runnable()
{
@Override
public void run()
{
callback.run(response);
}
});
}
};
handleDatabaseCall(new DatabaseRunnable(new Runnable()
@ -142,7 +164,7 @@ public class DonationRepository extends RepositoryBase
final Callback<Boolean> extraCallback = new Callback<Boolean>()
{
public void run(Boolean response)
public void run(final Boolean response)
{
if (response)
{
@ -150,8 +172,15 @@ public class DonationRepository extends RepositoryBase
executeUpdate(INSERT_COIN_TRANSACTION, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("reason", 100, "Rewarded by " + giver), new ColumnInt("coins", coins));
}
Bukkit.getServer().getScheduler().runTask(Plugin, new Runnable()
{
@Override
public void run()
{
callback.run(response);
}
});
}
};
handleDatabaseCall(new DatabaseRunnable(new Runnable()

View File

@ -1,26 +1,30 @@
package mineplex.enjinTranslator;
import java.text.SimpleDateFormat;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.NautHashMap;
import mineplex.core.common.util.UUIDFetcher;
import mineplex.core.donation.DonationManager;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.punish.Category;
import mineplex.core.punish.Punish;
import mineplex.core.server.remotecall.JsonWebCall;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@ -32,6 +36,10 @@ public class Enjin extends MiniPlugin implements CommandExecutor
private TempRepository _repository;
private NautHashMap<String, Entry<UUID, Long>> _cachedUUIDs = new NautHashMap<String, Entry<UUID, Long>>();
private List<QueuedCommand> _commandQueue = new ArrayList<QueuedCommand>();
private static Object _commandLock = new Object();
public long _lastPoll = System.currentTimeMillis() - 120000;
private SimpleDateFormat _dateFormat = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
@ -50,53 +58,153 @@ public class Enjin extends MiniPlugin implements CommandExecutor
plugin.getCommand("pull").setExecutor(this);
}
@EventHandler
public void expireCachedUUIDs(UpdateEvent event)
{
if (event.getType() != UpdateType.MIN_01)
return;
for (Iterator<Entry<String, Entry<UUID, Long>>> iterator = _cachedUUIDs.entrySet().iterator(); iterator.hasNext();)
{
Entry<String, Entry<UUID, Long>> entry = iterator.next();
if (System.currentTimeMillis() > entry.getValue().getValue())
iterator.remove();
}
}
@EventHandler
public void processCommandQueue(UpdateEvent event)
{
if (event.getType() != UpdateType.MIN_01 || _commandQueue.size() == 0)
return;
List<QueuedCommand> commandCopyQueue = new ArrayList<QueuedCommand>();
synchronized (_commandLock)
{
for (QueuedCommand command : _commandQueue)
commandCopyQueue.add(command);
_commandQueue.clear();
}
System.out.println("=====] Processing queued commands [=====");
for (QueuedCommand command : commandCopyQueue)
{
try
{
onCommand(command.Sender, command.Command, command.Label, command.Args);
}
catch (Exception exception)
{
exception.printStackTrace();
}
}
System.out.println("========================================");
}
@EventHandler
public void pollLastPurchases(UpdateEvent event)
{
if (event.getType() != UpdateType.MIN_01)
return;
//@SuppressWarnings("serial")
//List<EnjinPurchase> purchases = new JsonWebCall("http://www.mineplex.com/api/m-shopping-purchases/m/14702725").Execute(new TypeToken<List<EnjinPurchase>>(){}.getType(), null);
//_lastPoll = System.currentTimeMillis();
/*
@SuppressWarnings("serial")
List<EnjinPurchase> purchases = new JsonWebCall("http://www.mineplex.com/api/m-shopping-purchases/m/14702725").Execute(new TypeToken<List<EnjinPurchase>>(){}.getType(), null);
_lastPoll = System.currentTimeMillis();
int i = 0;
for (EnjinPurchase purchase : purchases)
{
if (i > 10)
break;
purchase.logInfoToConsole();
i++;
}
*/
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args)
{
synchronized (_commandLock)
{
try
{
if (sender instanceof Player)
((Player)sender).kickPlayer("Like bananas? I don't. Here take these and go have fun.");
if (label.equalsIgnoreCase("enjin_mineplex"))
{
final String name = args[1];
UUID playerUUID = null;
if (_cachedUUIDs.containsKey(name))
playerUUID = _cachedUUIDs.get(name).getKey();
else
{
// Fails if not in DB and if duplicate.
playerUUID = _clientManager.loadUUIDFromDB(name);
if (playerUUID == null)
playerUUID = UUIDFetcher.getUUIDOf(name);
}
_cachedUUIDs.put(name, new AbstractMap.SimpleEntry<UUID, Long>(playerUUID, System.currentTimeMillis() + 240000));
if (args.length == 3 && args[0].equalsIgnoreCase("gem"))
{
String name = args[1];
int amount = Integer.parseInt(args[2]);
final int amount = Integer.parseInt(args[2]);
_donationManager.RewardGems(null, "purchase", name, UUIDFetcher.getUUIDOf(name), amount);
_donationManager.RewardGems(new Callback<Boolean>()
{
public void run (Boolean response)
{
if (response)
{
System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " received " + amount + " gems.");
}
else
{
_commandQueue.add(new QueuedCommand(sender, command, label, args));
System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + " " + amount + " gems. Queuing for run later.");
}
}
}, "purchase", name, playerUUID, amount);
}
else if (args.length == 3 && args[0].equalsIgnoreCase("coin"))
{
String name = args[1];
int amount = Integer.parseInt(args[2]);
final int amount = Integer.parseInt(args[2]);
_donationManager.RewardCoins(null, "purchase", name, UUIDFetcher.getUUIDOf(name), amount);
_donationManager.RewardCoins(new Callback<Boolean>()
{
public void run (Boolean response)
{
if (response)
{
System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " received " + amount + " coins.");
}
else
{
_commandQueue.add(new QueuedCommand(sender, command, label, args));
System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + " " + amount + " coins. Queuing for run later.");
}
}
}, "purchase", name, playerUUID, amount);
}
else if (args.length == 3 && args[0].equalsIgnoreCase("booster"))
{
String name = args[1];
int amount = Integer.parseInt(args[2]);
_donationManager.PurchaseUnknownSalesPackage(null, name, UUIDFetcher.getUUIDOf(name), "Gem Booster " + amount, false, 0, false);
_donationManager.PurchaseUnknownSalesPackage(null, name, playerUUID, "Gem Booster " + amount, false, 0, false);
_repository.addGemBooster(name, amount);
System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " received " + amount + " Gem Boosters" + ".");
}
else if (args.length == 4 && args[0].equalsIgnoreCase("rank"))
{
final String name = args[1];
final String rank = args[2];
final boolean perm = Boolean.parseBoolean(args[3]);
@ -118,8 +226,6 @@ public class Enjin extends MiniPlugin implements CommandExecutor
}
else if (args.length >= 3 && args[0].equalsIgnoreCase("purchase"))
{
String name = args[1];
String packageName = args[2];
for (int i = 3; i < args.length; i++)
@ -127,12 +233,11 @@ public class Enjin extends MiniPlugin implements CommandExecutor
packageName += " " + args[i];
}
_donationManager.PurchaseUnknownSalesPackage(null, name, UUIDFetcher.getUUIDOf(name), packageName, false, 0, false);
_donationManager.PurchaseUnknownSalesPackage(null, name, playerUUID, packageName, false, 0, false);
System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " received " + packageName + ".");
}
else if (args.length >= 3 && args[0].equalsIgnoreCase("unban"))
{
String name = args[1];
String reason = args[2];
for (int i = 3; i < args.length; i++)
@ -145,7 +250,6 @@ public class Enjin extends MiniPlugin implements CommandExecutor
}
else if (args.length >= 3 && args[0].equalsIgnoreCase("ban"))
{
String name = args[1];
String reason = args[2];
for (int i = 3; i < args.length; i++)
@ -157,6 +261,12 @@ public class Enjin extends MiniPlugin implements CommandExecutor
System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " banned for " + reason);
}
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
}
return true;
}

View File

@ -0,0 +1,23 @@
package mineplex.enjinTranslator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class EnjinItem
{
public String item_name;
public double item_price;
public int item_id;
public Map<String, String> variables = new HashMap<String, String>();
public void logInfoToConsole()
{
System.out.println("item_id : " + item_id + ", item_name : " + item_name + ", item_price : " + item_price);
for (Entry<String, String> variable : variables.entrySet())
{
System.out.println("key : " + variable.getKey() + ", value : " + variable.getValue());
}
}
}

View File

@ -0,0 +1,27 @@
package mineplex.enjinTranslator;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
public class EnjinPurchase
{
private static SimpleDateFormat _dateFormat = new SimpleDateFormat();
public EnjinUser user;
public long purchase_date;
public String currency;
public String character;
public List<EnjinItem> items;
public void logInfoToConsole()
{
user.logInfoToConsole();
System.out.println(" MC Character : " + character + ", purchase_date : " + _dateFormat.format(new Date(purchase_date)) + ", currency : " + currency);
for (EnjinItem item : items)
{
item.logInfoToConsole();
}
}
}

View File

@ -0,0 +1,12 @@
package mineplex.enjinTranslator;
public class EnjinUser
{
public int user_id;
public String username;
public void logInfoToConsole()
{
System.out.println("user_id : " + user_id + ", username : " + username);
}
}

View File

@ -0,0 +1,20 @@
package mineplex.enjinTranslator;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class QueuedCommand
{
public CommandSender Sender;
public Command Command;
public String Label;
public String[] Args;
public QueuedCommand(CommandSender sender, Command command, String label, String[] args)
{
Sender = sender;
Command = command;
Label = label;
Args = args;
}
}

View File

@ -223,6 +223,7 @@
if (account == null)
return false;
token.OriginalBalance = account.Gems;
account.Gems += token.Amount;
if (!token.Source.Contains("Earned") && !token.Source.Contains("Tutorial") && !token.Source.Contains("Parkour"))
@ -241,6 +242,17 @@
repository.Edit(account);
repository.CommitChanges();
}
using (var repository = _repositoryFactory.CreateRepository())
{
var account = repository.Where<Account>(x => x.Name == token.Name).FirstOrDefault();
if (account == null)
return false;
if (account.Gems != token.OriginalBalance + token.Amount)
return false;
}
}
return true;
@ -275,7 +287,17 @@
repository.Edit(account);
repository.CommitChanges();
}
using (var repository = _repositoryFactory.CreateRepository())
{
var account = repository.Where<Account>(x => x.Name == token.Name).FirstOrDefault();
if (account == null)
return false;
if (account.Coins != token.OriginalBalance + token.Amount)
return false;
}
}
@ -568,7 +590,7 @@
}
}
public void ApplyKits(String name)
public bool ApplyKits(String name)
{
using (var repository = _repositoryFactory.CreateRepository())
{
@ -642,6 +664,8 @@
repository.CommitChanges();
}
return true;
}
public string UpdateRank(RankUpdateToken token)
@ -681,7 +705,7 @@
if (token.Retries >= 3)
_logger.Log("ERROR", "Applying UpdateRank, retried 3 times and something didn't stick.");
else if (!account.Rank.Name.Equals(token.Rank) || account.RankPerm != token.Perm || account.RankExpire != expire)
else if (!account.Rank.Name.Equals(token.Rank) || account.RankPerm != token.Perm || account.RankExpire.Equals(expire))
{
token.Retries++;
UpdateRank(token);

View File

@ -21,7 +21,7 @@
void ApplySalesPackage(SalesPackage salesPackage, int accountId, decimal gross, decimal fee);
Account Login(LoginRequestToken loginToken);
void Logout(string name);
void ApplyKits(string name);
bool ApplyKits(string name);
PunishmentResponse Punish(PunishToken punish);
PunishmentResponse RemovePunishment(RemovePunishmentToken ban);

File diff suppressed because it is too large Load Diff