Bulk query and fix double join bug
This commit is contained in:
parent
4d0ac23b45
commit
29a1619011
@ -116,7 +116,7 @@ public class MissionContext<T> implements Mission<T>
|
||||
private T _data;
|
||||
private LevelReward[] _rewards;
|
||||
|
||||
private int _minX, _maxX;
|
||||
private int _minX = 1, _maxX = 1;
|
||||
private int _minY, _maxY;
|
||||
|
||||
private boolean _eventMission;
|
||||
@ -139,7 +139,6 @@ public class MissionContext<T> implements Mission<T>
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public MissionBuilder<T> games(GameDisplay... games)
|
||||
{
|
||||
_games = games;
|
||||
|
@ -32,9 +32,9 @@ public enum MissionLength
|
||||
_calendarField = calendarField;
|
||||
}
|
||||
|
||||
public <T> PlayerMission<T> createFromContext(MissionContext<T> context, double rankBonus)
|
||||
public <T> PlayerMission<T> createFromContext(MissionContext<T> context)
|
||||
{
|
||||
return new PlayerMission<>(context, this, context.getRandomX(), context.getRandomY(), 0, rankBonus);
|
||||
return new PlayerMission<>(context, this, context.getRandomX(), context.getRandomY(), 0, true);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
|
@ -19,6 +19,8 @@ import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Slime;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import mineplex.core.MiniDbClientPlugin;
|
||||
import mineplex.core.ReflectivelyCreateMiniPlugin;
|
||||
@ -31,7 +33,6 @@ import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.donation.DonationManager;
|
||||
import mineplex.core.game.GameDisplay;
|
||||
import mineplex.core.mission.MissionRepository.MissionQuery;
|
||||
import mineplex.core.mission.commands.DebugMissionCommand;
|
||||
import mineplex.core.mission.commands.ViewMissionsCommand;
|
||||
import mineplex.core.mission.ui.MissionShop;
|
||||
@ -51,6 +52,10 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
DEBUG_MISSION_COMMAND
|
||||
}
|
||||
|
||||
private static final int MAX_DAILY = 5;
|
||||
private static final int MAX_WEEKLY = 3;
|
||||
private static final int MAX_TOTAL = MAX_DAILY + MAX_WEEKLY;
|
||||
|
||||
private static final String NPC_METADATA = "MISSION_NPC";
|
||||
private static final String NPC_NAME = C.cGreenB + "Sam The Slime";
|
||||
|
||||
@ -137,6 +142,7 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
MissionClient client = Get(uuid);
|
||||
TimeZone utc = TimeZone.getTimeZone("UTC");
|
||||
Calendar now = Calendar.getInstance(utc);
|
||||
int nonEventMissions = 0;
|
||||
|
||||
while (resultSet.next())
|
||||
{
|
||||
@ -149,12 +155,22 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
continue;
|
||||
}
|
||||
|
||||
// Here we attempt to fix a duplication bug caused by players joining US and EU at the same time.
|
||||
// How? well we know that players can have a maximum of 8 (non-event) missions total. So in that case
|
||||
// when they join a server with more than they should we'll clear everything from their 9th mission
|
||||
// onwards.
|
||||
if (!context.isEventMission() && ++nonEventMissions > MAX_TOTAL)
|
||||
{
|
||||
runAsync(() -> _repository.clearMission(accountId, missionId));
|
||||
continue;
|
||||
}
|
||||
|
||||
int progress = resultSet.getInt("progress");
|
||||
int length = resultSet.getInt("length");
|
||||
int x = resultSet.getInt("x");
|
||||
int y = resultSet.getInt("y");
|
||||
long startTime = resultSet.getLong("startTime");
|
||||
PlayerMission mission = new PlayerMission<>(context, MissionLength.values()[length], x, y, progress, getRankBonus(uuid));
|
||||
PlayerMission mission = new PlayerMission<>(context, MissionLength.values()[length], x, y, progress, false);
|
||||
|
||||
Calendar start = Calendar.getInstance(utc);
|
||||
start.setTimeInMillis(startTime);
|
||||
@ -162,7 +178,7 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
|
||||
if (lengthField != -1 && now.get(lengthField) != start.get(lengthField))
|
||||
{
|
||||
runAsync(() -> _repository.clearProgress(accountId, missionId));
|
||||
runAsync(() -> _repository.clearMission(accountId, missionId));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -183,19 +199,26 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
return "SELECT * FROM accountMissions WHERE accountId=" + accountId + ";";
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void playerJoin(PlayerJoinEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
double rankBonus = getRankBonus(player);
|
||||
|
||||
for (PlayerMission mission : Get(player).getMissions())
|
||||
{
|
||||
mission.createRewards(rankBonus);
|
||||
}
|
||||
|
||||
selectNewMissions(player);
|
||||
}
|
||||
|
||||
public void startMission(Player player, PlayerMission mission)
|
||||
{
|
||||
MissionClient client = Get(player);
|
||||
client.startMission(mission);
|
||||
|
||||
runAsync(() ->
|
||||
{
|
||||
if (!_repository.startMission(ClientManager.getAccountId(player), mission.getId(), mission.getLength().ordinal(), mission.getRequiredProgress(), mission.getY()))
|
||||
{
|
||||
client.getMissions().remove(mission);
|
||||
player.sendMessage(F.main(getName(), "Something went wrong when trying to start " + F.name(mission.getName()) + "."));
|
||||
}
|
||||
});
|
||||
_repository.addQueryToQueue(MissionRepository.startMission(ClientManager.getAccountId(player), () -> mission.createRewards(getRankBonus(player)), mission));
|
||||
}
|
||||
|
||||
private void completeMission(Player player, PlayerMission<?> mission)
|
||||
@ -221,7 +244,7 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
player.sendMessage("");
|
||||
player.playSound(player.getLocation(), Sound.LEVEL_UP, 1, (float) Math.random());
|
||||
|
||||
runAsync(() -> _repository.completeQuest(ClientManager.getAccountId(player), mission.getId()));
|
||||
runAsync(() -> _repository.completeMission(ClientManager.getAccountId(player), mission.getId()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -249,7 +272,6 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
{
|
||||
for (Player player : UtilServer.getPlayersCollection())
|
||||
{
|
||||
selectNewMissions(player);
|
||||
saveProgress(player);
|
||||
}
|
||||
|
||||
@ -271,7 +293,7 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
continue;
|
||||
}
|
||||
|
||||
startMission(player, MissionLength.EVENT.createFromContext(context, getRankBonus(player)));
|
||||
startMission(player, MissionLength.EVENT.createFromContext(context));
|
||||
started++;
|
||||
}
|
||||
|
||||
@ -294,7 +316,7 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
missions.removeIf(client::has);
|
||||
int started = 0;
|
||||
|
||||
for (int i = current; i <= max; i++)
|
||||
for (int i = current; i < max; i++)
|
||||
{
|
||||
MissionContext<?> context = UtilAlg.Random(missions);
|
||||
|
||||
@ -304,7 +326,7 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
}
|
||||
|
||||
missions.remove(context);
|
||||
startMission(player, length.createFromContext(context, getRankBonus(player)));
|
||||
startMission(player, length.createFromContext(context));
|
||||
started++;
|
||||
}
|
||||
|
||||
@ -344,13 +366,13 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
{
|
||||
boolean complete = mission.isComplete();
|
||||
|
||||
_repository.incrementProgress(new MissionQuery(accountId, mission, progress, () ->
|
||||
_repository.addQueryToQueue(MissionRepository.incrementProgress(accountId, () ->
|
||||
{
|
||||
if (complete)
|
||||
{
|
||||
runSync(() -> completeMission(player, mission));
|
||||
}
|
||||
}));
|
||||
}, progress, mission));
|
||||
});
|
||||
}
|
||||
|
||||
@ -363,11 +385,6 @@ public class MissionManager extends MiniDbClientPlugin<MissionClient>
|
||||
}
|
||||
|
||||
private double getRankBonus(Player player)
|
||||
{
|
||||
return getRankBonus(player.getUniqueId());
|
||||
}
|
||||
|
||||
private double getRankBonus(UUID player)
|
||||
{
|
||||
switch (ClientManager.Get(player).getPrimaryGroup())
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ import org.bukkit.Material;
|
||||
import mineplex.core.achievement.leveling.rewards.LevelCurrencyReward;
|
||||
import mineplex.core.achievement.leveling.rewards.LevelExperienceReward;
|
||||
import mineplex.core.common.currency.GlobalCurrency;
|
||||
import mineplex.core.game.GameDisplay;
|
||||
|
||||
import static mineplex.core.mission.MissionTrackerType.*;
|
||||
|
||||
@ -107,6 +108,7 @@ public class MissionPopulator
|
||||
MissionContext.<Material>newBuilder(manager, 100)
|
||||
.name("Enthusiast")
|
||||
.description("Play %s games.")
|
||||
.games(GameDisplay.values())
|
||||
.xRange(10, 50)
|
||||
.tracker(GAME_PLAY)
|
||||
.rewards(
|
||||
@ -119,6 +121,7 @@ public class MissionPopulator
|
||||
MissionContext.<Material>newBuilder(manager, 101)
|
||||
.name("Winner")
|
||||
.description("Win %s games.")
|
||||
.games(GameDisplay.values())
|
||||
.xRange(2, 10)
|
||||
.tracker(GAME_WIN)
|
||||
.rewards(
|
||||
@ -131,6 +134,7 @@ public class MissionPopulator
|
||||
MissionContext.<Material>newBuilder(manager, 102)
|
||||
.name("Killer")
|
||||
.description("Kill %s players in game.")
|
||||
.games(GameDisplay.values())
|
||||
.xRange(10, 50)
|
||||
.tracker(GAME_KILL)
|
||||
.rewards(
|
||||
@ -143,6 +147,7 @@ public class MissionPopulator
|
||||
MissionContext.<Material>newBuilder(manager, 103)
|
||||
.name("I Shall Taunt You A Second Time")
|
||||
.description("Taunt %s times in game.")
|
||||
.games(GameDisplay.values())
|
||||
.xRange(2, 20)
|
||||
.tracker(GAME_TAUNT)
|
||||
.rewards(
|
||||
|
@ -4,20 +4,49 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import mineplex.core.common.util.EnclosedObject;
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
import mineplex.serverdata.database.RepositoryBase;
|
||||
import mineplex.serverdata.database.column.ColumnByte;
|
||||
import mineplex.serverdata.database.column.ColumnInt;
|
||||
import mineplex.serverdata.database.column.ColumnLong;
|
||||
|
||||
public class MissionRepository extends RepositoryBase
|
||||
{
|
||||
|
||||
private static final String START_QUEST = "INSERT INTO accountMissions (accountId, missionId, length, x, y, startTime) VALUES (?,?,?,?,?,?);";
|
||||
private static final String START_MISSION = "INSERT INTO accountMissions (accountId, missionId, length, x, y, startTime) VALUES ({0},{1},{2},{3},{4},{5});";
|
||||
private static final String INCREMENT_PROGRESS = "UPDATE accountMissions SET progress=progress+{0} WHERE accountId={1} AND missionId={2};";
|
||||
private static final String COMPLETE_QUEST = "UPDATE accountMissions SET complete=1 WHERE accountId=? AND missionId=?;";
|
||||
private static final String IS_MISSION_COMPLETE = "SELECT complete FROM accountMissions WHERE accountId=? AND missionId=?;";
|
||||
private static final String COMPLETE_MISSION = "UPDATE accountMissions SET complete=1 WHERE accountId=? AND missionId=?;";
|
||||
private static final String CLEAR_PROGRESS = "DELETE FROM accountMissions WHERE accountId=? AND missionId=?;";
|
||||
|
||||
static MissionQuery startMission(int accountId, Runnable callback, PlayerMission mission)
|
||||
{
|
||||
return new MissionQuery(START_MISSION, accountId, callback, accountId, mission.getId(), mission.getLength().ordinal(), mission.getRequiredProgress(), mission.getY(), System.currentTimeMillis());
|
||||
}
|
||||
|
||||
static MissionQuery incrementProgress(int accountId, Runnable callback, int progress, Mission mission)
|
||||
{
|
||||
return new MissionQuery(INCREMENT_PROGRESS, accountId, callback, progress, accountId, mission.getId());
|
||||
}
|
||||
|
||||
static class MissionQuery
|
||||
{
|
||||
private final String _query;
|
||||
private final int _accountId;
|
||||
private final Runnable _callback;
|
||||
|
||||
MissionQuery(String query, int accountId, Runnable callback, Object... args)
|
||||
{
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
query = query.replace("{" + i + "}", String.valueOf(args[i]));
|
||||
}
|
||||
|
||||
_query = query;
|
||||
_accountId = accountId;
|
||||
_callback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
private final List<MissionQuery> _queries;
|
||||
|
||||
MissionRepository()
|
||||
@ -27,19 +56,7 @@ public class MissionRepository extends RepositoryBase
|
||||
_queries = new ArrayList<>();
|
||||
}
|
||||
|
||||
public boolean startMission(int accountId, int missionId, int lengthId, int x, int y)
|
||||
{
|
||||
return accountId != -1 && executeInsert(START_QUEST, null,
|
||||
new ColumnInt("accountId", accountId),
|
||||
new ColumnInt("missionId", missionId),
|
||||
new ColumnByte("length", (byte) lengthId),
|
||||
new ColumnInt("x", x),
|
||||
new ColumnInt("y", y),
|
||||
new ColumnLong("startTime", System.currentTimeMillis())
|
||||
) > 0;
|
||||
}
|
||||
|
||||
public void incrementProgress(MissionQuery query)
|
||||
public void addQueryToQueue(MissionQuery query)
|
||||
{
|
||||
if (query._accountId == -1)
|
||||
{
|
||||
@ -68,36 +85,39 @@ public class MissionRepository extends RepositoryBase
|
||||
_queries.clear();
|
||||
}
|
||||
|
||||
public boolean completeQuest(int accountId, int missionId)
|
||||
public boolean completeMission(int accountId, int missionId)
|
||||
{
|
||||
return accountId != -1 && executeUpdate(COMPLETE_QUEST,
|
||||
new ColumnInt("accountId", accountId),
|
||||
new ColumnInt("missionId", missionId)
|
||||
) > 0;
|
||||
return !isComplete(accountId, missionId) && executeUpdate(COMPLETE_MISSION, new ColumnInt("accountId", accountId), new ColumnInt("missionId", missionId)) > 0;
|
||||
}
|
||||
|
||||
public boolean clearProgress(int accountId, int missionId)
|
||||
public boolean isComplete(int accountId, int missionId)
|
||||
{
|
||||
if (accountId == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
EnclosedObject<Boolean> complete = new EnclosedObject<>(false);
|
||||
|
||||
executeQuery(IS_MISSION_COMPLETE, resultSet ->
|
||||
{
|
||||
while (resultSet.next())
|
||||
{
|
||||
complete.Set(resultSet.getBoolean("complete"));
|
||||
}
|
||||
},
|
||||
new ColumnInt("accountId", accountId),
|
||||
new ColumnInt("missionId", missionId)
|
||||
);
|
||||
|
||||
return complete.Get();
|
||||
}
|
||||
|
||||
public boolean clearMission(int accountId, int missionId)
|
||||
{
|
||||
return accountId != -1 && executeUpdate(CLEAR_PROGRESS,
|
||||
new ColumnInt("accountId", accountId),
|
||||
new ColumnInt("missionId", missionId)
|
||||
) > 0;
|
||||
}
|
||||
|
||||
static class MissionQuery
|
||||
{
|
||||
private final String _query;
|
||||
private final int _accountId;
|
||||
private final Runnable _callback;
|
||||
|
||||
MissionQuery(int accountId, Mission mission, int progress, Runnable callback)
|
||||
{
|
||||
_query = INCREMENT_PROGRESS
|
||||
.replace("{0}", String.valueOf(progress))
|
||||
.replace("{1}", String.valueOf(accountId))
|
||||
.replace("{2}", String.valueOf(mission.getId()));
|
||||
_accountId = accountId;
|
||||
_callback = callback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,35 +15,40 @@ public class PlayerMission<T> implements Mission<T>
|
||||
private final MissionLength _length;
|
||||
private final int _x;
|
||||
private final int _y;
|
||||
private final LevelReward[] _rewards;
|
||||
|
||||
private LevelReward[] _rewards;
|
||||
private int _currentProgress, _unsavedProgress;
|
||||
private boolean _rewarded;
|
||||
|
||||
PlayerMission(MissionContext<T> context, MissionLength length, int x, int y, int currentProgress, double rankBonus)
|
||||
PlayerMission(MissionContext<T> context, MissionLength length, int x, int y, int currentProgress, boolean fromContext)
|
||||
{
|
||||
_context = context;
|
||||
_length = length;
|
||||
|
||||
_x = x * length.getxScale();
|
||||
_x = fromContext && x > 1 ? x * length.getxScale() : x;
|
||||
_y = y;
|
||||
|
||||
if (_x == 0)
|
||||
{
|
||||
_description = String.format(context.getDescription(), _x, y);
|
||||
}
|
||||
else
|
||||
if (x == 1)
|
||||
{
|
||||
_description = String.format(context.getDescription(), y);
|
||||
}
|
||||
else
|
||||
{
|
||||
_description = String.format(context.getDescription(), _x, y);
|
||||
}
|
||||
|
||||
_currentProgress = currentProgress;
|
||||
}
|
||||
|
||||
public void createRewards(double rankBonus)
|
||||
{
|
||||
if (_x != 1 || rankBonus > 0)
|
||||
{
|
||||
_rewards = new LevelReward[context.getRewards().length];
|
||||
_rewards = new LevelReward[_context.getRewards().length];
|
||||
|
||||
for (int i = 0; i < _rewards.length; i++)
|
||||
{
|
||||
LevelReward reward = context.getRewards()[i];
|
||||
LevelReward reward = _context.getRewards()[i];
|
||||
|
||||
if (reward instanceof ScalableLevelReward)
|
||||
{
|
||||
@ -64,10 +69,8 @@ public class PlayerMission<T> implements Mission<T>
|
||||
}
|
||||
else
|
||||
{
|
||||
_rewards = context.getRewards();
|
||||
_rewards = _context.getRewards();
|
||||
}
|
||||
|
||||
_currentProgress = currentProgress;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -122,10 +122,10 @@ public class MissionMainPage extends ShopPageBase<MissionManager, MissionShop>
|
||||
if (lastLength == null || lastLength != mission.getLength())
|
||||
{
|
||||
lastLength = mission.getLength();
|
||||
column++;
|
||||
column = 0;
|
||||
}
|
||||
|
||||
addButtonNoAction(getSlot(row, column++), builder.build());
|
||||
addButtonNoAction(getSlot(row, ++column), builder.build());
|
||||
}
|
||||
|
||||
if (getItem(19) == null)
|
||||
|
Loading…
Reference in New Issue
Block a user