Skip to content

Instantly share code, notes, and snippets.

@mangstadt
Created April 11, 2014 21:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mangstadt/88398851bcd3f0e88c4d to your computer and use it in GitHub Desktop.
Save mangstadt/88398851bcd3f0e88c4d to your computer and use it in GitHub Desktop.
package com.empireminecraft.systems;
import com.empireminecraft.config.EmpireConfig;
import com.empireminecraft.config.meta.EmpireMetaKey;
import com.empireminecraft.data.EmpireUser;
import com.empireminecraft.data.items.PromoItems;
import com.empireminecraft.data.items.VotingItems;
import com.empireminecraft.features.EmpireRupees;
import com.empireminecraft.features.items.CustomItem;
import com.empireminecraft.systems.db.DbRow;
import com.empireminecraft.systems.db.DbStatement;
import com.empireminecraft.util.TaskChain;
import com.empireminecraft.util.Util;
import org.bukkit.Material;
import java.util.Calendar;
import java.util.GregorianCalendar;
import static com.empireminecraft.features.Mail.sendSystemMail;
public class Voting {
private static final int STREAK_INTERVAL = 60 * 60 * 36; //**use constants for streak settings
private static final int STREAK_INCREASE = 60 * 60 * 16;
private static final int STREAK_LOSS = 60 * 60 * 24 * 3;
public static void creditVote(final String player, final String service) {
if (!EmpireUser.validateUsername(player)) {
Util.log("Could not validate user name " + player);
return;
}
if (service == null) {
Util.logWarning("Player " + player + " voted with unknown service");
return;
}
final VotingTask task = new VotingTask(player, service);
TaskChain.newChain().add(task).execute();
}
private static class VotingTask implements TaskChain.GenericTask { //**make this class implement GenericTask
private String player;
private String service;
private Long voteBonus;
private VotingTask(String player, String service) {
this.player = player;
this.service = service;
}
@Override
protected void run(){
try (DbStatement stm = new DbStatement()) {
stm.startTransaction();
stm.query("SELECT " +
"lastvote, votebonus, voteitembonus, " +
"user_id, votemax, votelastmiss " +
"FROM user WHERE name = ? FOR UPDATE");
stm.execute(player);
DbRow rs = stm.getNextRow();
if (rs == null) {
Util.log("[vote] Could not find user '" + player + "' for '" + service + "'");
return;
}
Long userId = rs.get("user_id"); //** variables don't need to be defined at class level
voteBonus = rs.get("votebonus");
Long lastVote = rs.get("lastvote");
Long voteMax = rs.get("votemax");
Long voteMissed = rs.get("votelastmiss");
int voteRupees = EmpireConfig.get().getInt("vote-rewards." + Util.simplifyString(service), 100);
long timestamp = System.currentTimeMillis() / 1000;
if (timestamp - lastVote < STREAK_INTERVAL) {
final EmpireUser user = EmpireUser.getUser(player);
player = user.getName();
final Long lastBonus = user.getMeta(EmpireMetaKey.VOTE_LAST_BONUS).getLong();
if (lastBonus == null || timestamp - lastBonus > STREAK_INCREASE) {
voteRupees += 100;
voteRupees += Math.min(voteBonus++ * 10, 500);
if (voteBonus > voteMax) {
voteRupees += calculateRupeeBonus(); //** method can return the bonus amount
processItemBonus();
}
user.setMeta(EmpireMetaKey.VOTE_LAST_BONUS, timestamp);
}
} else if (lastVote < timestamp - STREAK_LOSS) { // 3 day window before losing streak
long daysMissed = (timestamp - lastVote) / (60 * 60 * 24); //** don't need to call Math.floor() because they're all integers/longs
voteBonus = Math.max(0, voteBonus - daysMissed);
voteMissed = timestamp;
}
lastVote = timestamp;
stm.query("UPDATE user SET votes = votes + 1, "
+ " lastvote = ?, votebonus = ?, votemax = ?, votelastmiss = ? WHERE user_id = ?");
stm.executeUpdate(
lastVote,
voteBonus,
Math.max(voteBonus, voteMax),
voteMissed,
userId);
stm.commit();
EmpireRupees.credit(userId, voteRupees, 31, service + " - day bonus: " + voteBonus);
Util.notifyPlayer(player, "&aYou successfully voted on&f " + service + " &aand earned &f" + voteRupees + "&a rupees!");
if (voteBonus > voteMax) {
Util.notifyPlayer(player, "&aYour vote bonus is now &f" + voteBonus + "&a! Keep up the good work!");
}
Util.log("[vote] '" + player + "' voted on '" + service + "' and earned: " + voteRupees +
" rupees with mod:" + voteBonus);
} catch (Throwable t) { //**catch "Throwable" so runtime exceptions are caught too
Util.printException("[vote] FAILED for '" + player + "' on '" + service + "'", t);
}
}
private int calculateRupeeBonus() { //**method returns bonus
/*
* DO NOT add any other logic after shouldGet* - do it BEFORE. If
* one of the shouldGetItem returns true, it must deliver item.
*/
if (shouldGetEvery(5, "rupee5")) {
return 300;
}
if (shouldGetEvery(15, "rupee15")) {
return 1000;
}
if (shouldGetEvery(30, "rupee30")) {
return 4000;
}
if (shouldGetEvery(45, "rupee45")) {
return 7500;
}
if (shouldGetEvery(50, "rupee50")) {
return 25000;
}
if (shouldGetEvery(100, "rupee100")) {
return 40000;
}
return 0;
}
private void processItemBonus() {
String subject = "Vote Bonus " + voteBonus + " Reward";
/*
* DO NOT add any other logic after shouldGet* - do it BEFORE. If
* one of the shouldGetItem returns true, it must deliver item.
*/
if (shouldGetEvery(2, "diamond")) {
sendSystemMail(player, subject, CustomItem.newItem(Material.DIAMOND).withRange(1, Math.max(1, (int) Math.min(10, voteBonus / 5))).getDrop(0));
}
if (shouldGetEvery(3, "emerald")) {
sendSystemMail(player, subject, CustomItem.newItem(Material.EMERALD).withRange(1, Math.max(1, (int) Math.min(10, voteBonus / 5))).getDrop(0));
}
if (shouldGetEvery(20, "vaultVoucher")) {
sendSystemMail(player, subject, PromoItems.VAULT_VOUCHER);
}
if (shouldGetEvery(50, "stableVoucher")) {
sendSystemMail(player, subject, PromoItems.STABLE_VOUCHER);
}
if (shouldGetAt(20, "votersBoots")) {
sendSystemMail(player, subject, VotingItems.makeVotingItem(player, VotingItems.VOTERS_BOOTS));
}
if (shouldGetAt(30, "votersHead")) {
sendSystemMail(player, subject, VotingItems.makeVotingItem(player, VotingItems.VOTERS_HEAD));
}
if (shouldGetAt(40, "votersLegs")) {
sendSystemMail(player, subject, VotingItems.makeVotingItem(player, VotingItems.VOTERS_LEGS));
}
if (shouldGetAt(60, "votersChest")) {
sendSystemMail(player, subject, VotingItems.makeVotingItem(player, VotingItems.VOTERS_CHEST));
}
if (shouldGetAt(100, "tyCertificate")) {
sendSystemMail(player, subject, VotingItems.makeVotingThankYou(player));
}
}
private boolean shouldGetEvery(int i, String key) {
if (shouldGetAt(i, key)) {
return true;
}
if ((voteBonus % i == 0) && !hasMetaKey(key + voteBonus)) {
setMetaKey(key + voteBonus);
return true;
}
return false;
}
private boolean shouldGetAt(int i, String key) {
if (voteBonus >= i && !hasMetaKey(key + i)) {
setMetaKey(key + i);
return true;
}
return false;
}
private void setMetaKey(String key) {
EmpireMetaKey metaKey = createMetaKey(key);
EmpireUser.getUser(player).setMeta(metaKey, "1");
}
private boolean hasMetaKey(String key) {
EmpireMetaKey metaKey = createMetaKey(key);
return EmpireUser.getUser(player).getMeta(metaKey).getString() != null;
}
private EmpireMetaKey getMetaKey(String key){ //**create method to remove duplicate code
return new EmpireMetaKey("votereward." + key, 0);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment